jestの環境構築をしていて、import/export
が使えなかったり、.jsx
の取り扱いでハマったので調べたことをまとめる。
CommonJSとESModule
JavaScriptには、モジュールの取り扱いのための仕様が2つ存在する。
jestでそのままimport/exportが使用できないのはここに起因する。
CommonJS
CommonJSとは、サーバーサイドなどのウェブブラウザ環境外におけるJavaScriptの各種仕様を定めることを目標としたプロジェクトである。
Node.jsが標準で採用している。jestも同様。
モジュールの読み込みはrequire
、モジュールの公開はmodule.exports
などを使用する。
ファイルの拡張子を.js
とするとCommonJSで扱われる。
ESModule
ECMAScript(エクマスクリプト)は、Ecma Internationalのもとで標準化手続きが行われているJavaScriptの規格
最近の主流はこっちらしい。
モジュールの読み込みはimport
、モジュールの公開はexport
を使用する。
ESModuleとして実行するためには、package.json
に設定を追加するか、ファイルの拡張子を.mjs
とする。
{
"type": "module",
"main": "./main.js"
}
jestはcommonJSを採用しているので、ESModuleの記法であるimport/export
はそのままでは使用できないということらしい。
また、.jsx
もそのままでは取り扱えない様子。
そのため、Babelを導入して各種変換をかます必要があるらしい。
Babelの導入
必要なのは以下の4つ。
- Babelの導入
-
@babel/preset-react
の導入
.jsx
から.js
への変換のために必要。 -
@babel/preset-env
の導入
ESModuleからCommonJSへの変換に必要。 - jestのtestEnvironmentを
jsdom
に変更
ブラウザ環境でのテストに必要。デフォルトはnode
。
babelと.jsx
から.js
へ変換するためのパッケージをインストールする。
npm install babel @babel/preset-react --save-dev
babel.config.json
というファイルを以下の内容で作成する。
このファイルがないと、babelは何も変換処理を実施しない。
{
"presets": ["@babel/preset-react"]
}
次に、ESModuleからCommonJSへの変換をするためのパッケージをインストールする。
npm install @babel/preset-env --save-dev
その後、babel.config.json
を以下のように変更する。
{
"presets": [
["@babel/preset-react", { "runtime": "automatic" }],
["@babel/preset-env", { "targets": { "node": "current" } }]
]
}
ブラウザでの実行を想定しているテストの場合、テスト実行環境をnode
からjsdom
に変更する必要がある。
jsdom
を利用可能とするため、下記パッケージをインストールする。
npm install jest-environment-jsdom --save-dev
その後、jest.config.json
を以下の内容で作成する。
{
"testEnvironment": "jest-environment-jsdom"
}
expect(...).toBeInTheDocument is not a function
が出る場合は、@testing-library/jest-dom
をインストールし、
npm install @testing-library/jest-dom --save-dev
テストファイルにimport '@testing-library/jest-dom'
を記載する。
参考