neputa note

AstroのユニットテストをJestで行う【ESモジュール対処法】

初稿:

- 5 min read -

img of AstroのユニットテストをJestで行う【ESモジュール対処法】

記事概要

  • 先日のBloggerからAstroへ移行した記事の別途詳細
  • AstroのBlogテンプレートにJestを追加し実行するまでをまとめる
  • Astroは通常のESM(ECMAScript Modules)を使用しており、Jest側で対処が必要
  • 既存のtsconfigは手を加えず、別途テスト用にtsconfigを作成しこれを回避する
  • 最後にJestのVSCode拡張機能を紹介

※参考 - Blog移行記事

BlogをBloggerからAstroへ移行した

10年以上の期間お世話になったGoogle Bloggerに別れを告げ、この度AstroでBlogサイトを構築し移行した。Astroは静的サイトを手軽に開発できる軽量フレームワーク。無料のテンプレートをベースにカスタマイズを行った。それなりの作業ボリュームとなったので、詳細は別記事に分け、今回は移行作業全体をまとめる。

ESM・ESモジュール(ECMAScript Modules)とは

ES Modules入門 - JavaScriptのモジュールを使う方法 - ICS MEDIA

JavaScriptには、モジュールという仕組みがあります。ECMAScript2015のModulesの標準仕様として策定されており、現在はすべてのブラウザで利用できます。

環境

  • Node.js - v20.14.0
  • pnpm - v9.4.0
  • Jest - v29.7.0
  • typescript - v5.5.2
  • VSCode - v1.90.2

Jest について

Jest

Jest はシンプルさを重視した、快適な JavaScript テスティングフレームワークです。Babel、TypeScript、Node、React、Angular、Vue など、様々なフレームワークを利用したプロジェクトで動作します!

前提

  • Node.js環境(pnpm使用)
  • Astroの既存プロジェクトにJestを追加する(Astro固有の設定等は特になし)

インストールと設定

  • Jest、TypeScript、そのほか関連パッケージをインストール
install-packages
pnpm add --save-dev typescript jest ts-jest @types/jest
  • jest.config.js を作成
create-jest.config.js
pnpm ts-jest config:init
  • Astroテンプレートのtsconfigが既にあるのでjestを実行することはできる
  • 試しにモジュールとテストファイルを作成しjestを実行する
sample.ts
export function writeLog(log: string) {
  return console.log(log)
}
initial.test.ts
import { writeLog } from '../src/utils/sample'

test('最初のテスト', () => {
  writeLog('OK')
})
  • するとverbatimModuleSyntaxがenabledの時のCommonJSではモジュールのimportはダメと怒られる
jest-error
$ pnpm jest
 FAIL  test/initial.test.ts
 Test suite failed to run

    test/initial.test.ts:1:10 - error TS1286: ESM syntax is not allowed in a CommonJS module when 'verbatimModuleSyntax' is enabled.

    1 import { writeLog } from '../src/utils/sample'
               ~~~~~~~~

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        2.513 s
Ran all test suites.
tsconfig.test.json
{
  "compilerOptions": {
    "target": "es2021",
    "module": "commonjs",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true
  }
}
  • これをjest.config.jsに登録する
  • jest.config.jsのpresetを修正し、transformを追加する
jest.config.js
/* prettier-ignore */
/** @type {import('ts-jest').JestConfigWithTsJest} */
export default {
  preset: 'ts-jest', 
  preset: 'ts-jest/presets/default-esm', 
  testEnvironment: 'node',
  transform: { 
    '^.+\\.ts?$': [ 
      'ts-jest', 
      { 
        useESM: true, 
        tsconfig: 'tsconfig.test.json'
      } 
    ] 
  } 
}

テスト実行

  • Jestは拡張子の前に「.test」を付与したファイルを見つけ出しテストを実行する
  • 先ほどエラーを確認したファイルは「test/initial.test.ts」
  • pnpm jestコマンドでテストを実行する
jest-success
$ pnpm jest
  console.log
    OK

      at writeLog (src/utils/sample.ts:2:17)

 PASS  test/initial.test.ts
 最初のテスト (14 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.792 s
Ran all test suites.
  • 今度は無事に実行できた

VSCode拡張機能

  • 便利なVSCode拡張機能があった

Jest - Visual Studio Marketplace

Extension for Visual Studio Code - Use Facebook's Jest With Pleasure.

  • Market PlaceまたはVSCodeからインストールする
  • プロジェクトのルートに .vscodeディレクトリを無ければ作成する
  • .vscodeにsettings.jesonを作成し以下を記述(今回はpnpmを使用している)
settings.json
{
  "jest.jestCommandLine": "pnpm jest"
}
  • VSCodeをリロードするとサイドバーにフラスコのアイコンが表示される
  • ここでテストファイルやテスト関数を管理することができる

VSCodeテストアイコン

まとめ

  • 不慣れなTypeScriptでコードを書くにあたり、ユニットテストを実行できる環境がいち早くほしかった
  • Jestを知りインストールしたが設定に苦労する
  • 既存の環境に手を付けずに対処する方法が分からず手間取ったので備忘録としてまとめてみた

参考サイト

目次