Jest で TypeScript テスト: エラー "Cannot use import statement outside a module" の原因と解決策
プログラミング: Jest で "Cannot use import statement outside a module" エラーが発生する原因と解決策
Jest でテストを実行中に SyntaxError: Cannot use import statement outside a module
エラーが発生する場合、Jest が ES モジュール構文を認識および変換できないことが原因です。ES モジュールは、JavaScript の最新バージョンで導入された新しいモジュールシステムです。
原因:
このエラーが発生する主な理由は2つあります。
- Jest の設定: Jest はデフォルトでは、
node_modules
ディレクトリ内のファイルをトランスパイルしません。そのため、node_modules
内のモジュールが ES モジュールの構文を使用している場合、このエラーが発生する可能性があります。 - Babel の設定: Babel は、ES モジュールの構文を JavaScript の古いバージョンにトランスパイルするために使用されます。Babel が正しく設定されていない場合、Jest が ES モジュール構文を認識できなくなる可能性があります。
解決策:
このエラーを解決するには、以下の手順を実行します。
Jest 設定ファイル (jest.config.js
) に以下の設定を追加します。
module.exports = {
transform: {
"^.+\\.js$": "babel-jest",
"^.+\\.ts$": "ts-jest"
},
transformIgnorePatterns: [
"/node_modules/"
]
};
この設定により、Jest はすべての .js
ファイルと .ts
ファイルを Babel でトランスパイルし、node_modules
ディレクトリ内のファイルを無視するように指示されます。
Babel の設定:
プロジェクトのルートディレクトリにある babel.config.js
ファイルに以下の設定を追加します。
module.exports = {
presets: [
"@babel/preset-env",
"@babel/preset-typescript"
],
plugins: [
"@babel/plugin-transform-runtime",
"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-decorators"
]
};
この設定により、Babel は ES モジュールの構文をトランスパイルするために必要なプリセットとプラグインを使用するように指示されます。
TypeScript プロジェクトの場合は、tsconfig.json
ファイルに以下の設定を追加します。
{
"compilerOptions": {
"allowJs": true
}
}
この設定により、TypeScript コンパイラは JavaScript ファイルを処理できるように指示されます。
上記の設定に加えて、以下の点にも注意する必要があります。:
- Jest と Babel のバージョンが互換性があることを確認してください。
- プロジェクトのルートディレクトリに
.babelrc
ファイルがある場合は、その内容を確認してください。 node_modules
ディレクトリ内に古いバージョンの Babel プリセットが含まれていないことを確認してください。
サンプルコード: Jest で TypeScript モジュールをテストする
ファイル構成:
src/
├── index.ts
└── square.ts
tests/
└── square.test.ts
コード:
src/index.ts:
import { square } from './square';
console.log(square(5)); // 25
src/square.ts:
export function square(n: number): number {
return n * n;
}
tests/square.test.ts:
import { square } from '../src/square';
describe('square', () => {
it('should square a number', () => {
expect(square(5)).toBe(25);
});
});
実行方法:
以下のコマンドを実行して、テストを実行します。
npx jest
出力:
PASS tests/square.test.ts (1.63s)
square
✓ should square a number (1.63s)
Test Suites: 1 passed, 1 total
100% success (1.64s)
説明:
- index.ts: このファイルは、
square
関数をsquare.ts
モジュールからインポートし、5 をsquare
関数に渡して結果を出力します。 - square.ts: このファイルは、
square
関数を定義します。この関数は、引数として渡された数値を平方します。 - square.test.ts: このファイルは、Jest を使用して
square
関数をテストします。describe
ブロックは、テスト対象のモジュールまたは機能を定義します。it
ブロックは、個々のテストケースを定義します。
このサンプルコードは、Jest で TypeScript モジュールをテストする基本的な方法を示しています。 より複雑なテストを書くには、Jest のドキュメントと Babel のドキュメントを参照してください。
補足:
- 上記のサンプルコードでは、
jest.config.js
と.babelrc
ファイルは必要ありません。Jest はデフォルトで、node_modules
ディレクトリ内のファイルをトランスパイルし、ES モジュールの構文を認識します。 - TypeScript コンパイラは、TypeScript ファイルを JavaScript ファイルにコンパイルする必要があります。コンパイルするには、以下のコマンドを実行します。
npx tsc
このコマンドを実行すると、src
ディレクトリ内のすべての .ts
ファイルが src
ディレクトリ内に *.js
ファイルとしてコンパイルされます。
- Jest と Babel の詳細については、それぞれのドキュメントを参照してください。
- TypeScript の詳細については、TypeScript のドキュメントを参照してください。
Jest で TypeScript モジュールをテストするその他の方法
ts-jest を使用する:
ts-jest
は、Jest と一緒に使用できる TypeScript 用のテストランナーです。ts-jest
を使用すると、Jest の設定を変更せずに TypeScript モジュールをテストできます。
インストール:
npm install --save-dev ts-jest
使用方法:
ts-jest
を使用するには、以下のコマンドを実行します。
npx ts-jest
Jest CLI オプションを使用する:
Jest CLI には、TypeScript ファイルをトランスパイルするためのオプションがいくつか用意されています。これらのオプションを使用して、Jest の設定を変更せずに TypeScript モジュールをテストできます。
使用可能なオプション:
--transform-typescript
: このオプションは、Jest に TypeScript ファイルをトランスパイルするように指示します。--module
: このオプションは、Jest に ES モジュールを使用するように指示します。--resolve-json-module-relative
: このオプションは、Jest に JSON モジュールを相対パスで解決するように指示します。
以下のコマンドを実行して、--transform-typescript
オプションと --module
オプションを使用して TypeScript モジュールをテストします。
npx jest --transform-typescript --module
手動で TypeScript をトランスパイルする:
TypeScript コンパイラ (tsc
) を使用して、手動で TypeScript ファイルを JavaScript ファイルにトランスパイルしてから、Jest でテストすることもできます。
手順:
- 以下のコマンドを実行して、TypeScript ファイルを JavaScript ファイルにトランスパイルします。
npx tsc
- 以下のコマンドを実行して、トランスパイルされた JavaScript ファイルを Jest でテストします。
npx jest
注意事項:
- 上記の方法は、単純なプロジェクトでのみ推奨されます。
- 大規模なプロジェクトでは、
ts-jest
または Jest CLI オプションを使用する方が簡単で効率的です。
これらの方法は、それぞれ異なる利点と欠点があります。プロジェクトのニーズに合った方法を選択してください。
typescript jestjs babel-jest