Using with webpack
Jestは webpackでアセットやスタイル、コンパイル作業を管理するプロジェクトで使用できます。 webpackはJavaScript代替言語とツールの拡張的なエコシステムに加えて、スタイルシート、画像やフォントのようなアセットの管理を可能にするためにアプリケーションに直接結合するので、他の同様のツールと比べて実にユニークで挑戦的な機能を提供しています。
webpackの設定例
一般的な種類のwebpackの設定ファイルから始めて、Jestのセットアップに変換してみましょう。
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モジュールを利用している場合はクラス名参照のためのプロキシをモックした方が良いでしょう。
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',
},
};
そしてモックファイル自身は次のようになります:
module.exports = {};
module.exports = 'test-file-stub';
CSSモジュールのモック
CSS ModulesをモックするにはES6 Proxyを使用します:
- npm
- Yarn
- pnpm
npm install --save-dev identity-obj-proxy
yarn add --dev identity-obj-proxy
pnpm add --save-dev identity-obj-proxy
スタイルオブジェクトの全てのクラス名参照はそのまま返るようになります(つまりstyles.foobar === 'foobar'
となります)。 この挙動は React の Snapshot のテストに とても便利です。
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'
に変換)は、次のように記述してください:
const path = require('path');
module.exports = {
process(sourceText, sourcePath, options) {
return {
code: `module.exports = ${JSON.stringify(path.basename(sourcePath))};`,
};
},
};
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
transformer を明示的に含めることを忘れないでください。
"transform": {
"\\.[jt]sx?$": "babel-jest",
"\\.css$": "some-css-transformer",
}
ソースファイルを探索できるようにJestを設定する
ここまででJestはファイルの処理方法を理解したので、次はJestにファイルを 見つける方法を教えてやる必要があります。 For webpack's modules
, and extensions
options there are direct analogs in Jest's moduleDirectories
and moduleFileExtensions
options.
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>
is a special token that gets replaced by Jest with the root of your project. Most of the time this will be the folder where your package.json
is located unless you specify a custom rootDir
option in your configuration.
Similarly, Jest's counterpart for Webpack's resolve.roots
(an alternative to setting NODE_PATH
) is modulePaths
.
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',
},
};
And finally, we have to handle the webpack alias
. For that, we can make use of the moduleNameMapper
option again.
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の設定を調整するよりも十分な柔軟性を持っているはずです。
For more complex webpack configurations, you may also want to investigate projects such as: babel-plugin-webpack-loaders.
Using with webpack
In addition to installing babel-jest
as described earlier, you'll need to add @babel/preset-env
like so:
- npm
- Yarn
- pnpm
npm install --save-dev @babel/preset-env
yarn add --dev @babel/preset-env
pnpm add --save-dev @babel/preset-env
Then, you'll want to configure Babel as follows:
{
"presets": ["@babel/preset-env"]
}
Jest caches files to speed up test execution. If you updated .babelrc
and Jest is not working as expected, try clearing the cache by running jest --clearCache
.
import('some-file.js').then (module = >...)
のように動的インポートを使用する場合は、 dynamic-import-node
プラグインを有効にする必要があります。
{
"presets": [["env", {"modules": false}]],
"plugins": ["syntax-dynamic-import"],
"env": {
"test": {
"plugins": ["dynamic-import-node"]
}
}
}
For an example of how to use Jest with webpack with React, you can view one here.