メインコンテンツへスキップ
バージョン: 29.7

webpackでの利用

Jestは、アセット、スタイル、コンパイルを管理するためにwebpackを使用するプロジェクトで使用できます。webpackは、スタイルシート、画像やフォントなどのアセット、およびコンパイル先のJavaScript言語とツールの広範なエコシステムを管理できるようにアプリケーションと直接統合されているため、他のツールよりも特有の課題があります。

webpackの例

一般的なwebpack設定ファイルから始めて、それをJestの設定に変換しましょう。

webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.jsx?$/,
exclude: ['node_modules'],
use: ['babel-loader'],
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.gif$/,
type: 'asset/inline',
},
{
test: /\.(ttf|eot|svg)$/,
type: 'asset/resource',
},
],
},
resolve: {
alias: {
config$: './configs/app-config.js',
react: './vendor/react-master',
},
extensions: ['.js', '.jsx'],
modules: [
'node_modules',
'bower_components',
'shared',
'/shared/vendor/modules',
],
},
};

Babelで変換されたJavaScriptファイルがある場合は、babel-jestプラグインをインストールしてBabelのサポートを有効にすることができます。Babel以外のJavaScript変換は、Jestのtransform設定オプションで処理できます。

静的アセットの処理

次に、スタイルシートや画像などのアセットファイルを適切に処理するようにJestを設定しましょう。通常、これらのファイルはテストでは特に有用ではないため、安全にモック化できます。ただし、CSS Modulesを使用している場合は、classNameルックアップのプロキシをモック化する方が適切です。

jest.config.js
module.exports = {
moduleNameMapper: {
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/__mocks__/fileMock.js',
'\\.(css|less)$': '<rootDir>/__mocks__/styleMock.js',
},
};

そして、モックファイル自体

__mocks__/styleMock.js
module.exports = {};
__mocks__/fileMock.js
module.exports = 'test-file-stub';

CSS Modulesのモック化

ES6プロキシを使用してCSS Modulesをモック化できます。

npm install --save-dev identity-obj-proxy

すると、スタイルオブジェクトに対するすべてのclassNameルックアップはそのまま返されます(例:styles.foobar === 'foobar')。これは、Reactのスナップショットテストに非常に便利です。

jest.config.js(CSS Modules用)
module.exports = {
moduleNameMapper: {
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/__mocks__/fileMock.js',
'\\.(css|less)$': 'identity-obj-proxy',
},
};

moduleNameMapperで要件を満たせない場合は、Jestのtransform設定オプションを使用して、アセットがどのように変換されるかを指定できます。たとえば、ファイルのベース名を返すトランスフォーマー(require('logo.jpg');'logo'を返すように)は、次のように記述できます。

fileTransformer.js
const path = require('path');

module.exports = {
process(sourceText, sourcePath, options) {
return {
code: `module.exports = ${JSON.stringify(path.basename(sourcePath))};`,
};
},
};
jest.config.js(カスタムトランスフォーマーとCSS Modules用)
module.exports = {
moduleNameMapper: {
'\\.(css|less)$': 'identity-obj-proxy',
},
transform: {
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/fileTransformer.js',
},
};

スタイルシートまたは画像の拡張子に一致するファイルを無視し、代わりにモックファイルを要求するようにJestに指示しました。正規表現を調整して、webpack設定で処理するファイルタイプに一致させることができます。

ヒント

追加のコードプリプロセッサと一緒に使用する場合は、デフォルトのbabel-jestトランスフォーマーを明示的に含めることを忘れないでください。

"transform": {
"\\.[jt]sx?$": "babel-jest",
"\\.css$": "some-css-transformer",
}

Jestがファイルを検出するように構成する

Jestがファイルを処理する方法を理解したので、次にファイルを検出する方法をJestに指示する必要があります。webpackのmodulesおよびextensionsオプションには、JestのmoduleDirectoriesおよびmoduleFileExtensionsオプションに直接対応するものがあります。

jest.config.js
module.exports = {
moduleFileExtensions: ['js', 'jsx'],
moduleDirectories: ['node_modules', 'bower_components', 'shared'],

moduleNameMapper: {
'\\.(css|less)$': '<rootDir>/__mocks__/styleMock.js',
'\\.(gif|ttf|eot|svg)$': '<rootDir>/__mocks__/fileMock.js',
},
};
注意

<rootDir>は、プロジェクトのルートでJestによって置き換えられる特別なトークンです。構成でカスタムのrootDirオプションを指定しない限り、通常はpackage.jsonが配置されているフォルダーになります。

同様に、Webpackのresolve.rootsNODE_PATHを設定する代替手段)に対応するJestはmodulePathsです。

jest.config.js
module.exports = {
modulePaths: ['/shared/vendor/modules'],
moduleFileExtensions: ['js', 'jsx'],
moduleDirectories: ['node_modules', 'bower_components', 'shared'],
moduleNameMapper: {
'\\.(css|less)$': '<rootDir>/__mocks__/styleMock.js',
'\\.(gif|ttf|eot|svg)$': '<rootDir>/__mocks__/fileMock.js',
},
};

最後に、webpackのaliasを処理する必要があります。そのためには、再びmoduleNameMapperオプションを利用できます。

jest.config.js
module.exports = {
modulePaths: ['/shared/vendor/modules'],
moduleFileExtensions: ['js', 'jsx'],
moduleDirectories: ['node_modules', 'bower_components', 'shared'],

moduleNameMapper: {
'\\.(css|less)$': '<rootDir>/__mocks__/styleMock.js',
'\\.(gif|ttf|eot|svg)$': '<rootDir>/__mocks__/fileMock.js',

'^react(.*)$': '<rootDir>/vendor/react-master$1',
'^config$': '<rootDir>/configs/app-config.js',
},
};

以上です! webpackは複雑で柔軟なツールであるため、特定のアプリケーションのニーズに合わせて調整する必要がある場合があります。幸いなことに、ほとんどのプロジェクトでは、Jestはwebpack設定を処理するのに十分な柔軟性を備えているはずです。

ヒント

より複雑なwebpack構成については、babel-plugin-webpack-loadersなどのプロジェクトを調査することもできます。

webpackでの利用

前述のようにbabel-jestをインストールすることに加えて、次のように@babel/preset-envを追加する必要があります。

npm install --save-dev @babel/preset-env

次に、次のようにBabelを構成します。

.babelrc
{
"presets": ["@babel/preset-env"]
}
ヒント

Jestはテスト実行を高速化するためにファイルをキャッシュします。.babelrcを更新したのにJestが期待どおりに動作しない場合は、jest --clearCacheを実行してキャッシュをクリアしてみてください。

ヒント

動的インポート(import('some-file.js').then(module => ...))を使用する場合は、dynamic-import-nodeプラグインを有効にする必要があります。

.babelrc
{
"presets": [["env", {"modules": false}]],

"plugins": ["syntax-dynamic-import"],

"env": {
"test": {
"plugins": ["dynamic-import-node"]
}
}
}

Reactでwebpackを使用するJestの使用方法の例については、こちらをご覧ください。