JavaScript
Jest
babel
babel-jest

.babelrcを使わずに独自のBabelの設定を使ってJestを実行する

この記事は.babelrcの設定を使わずにJest用の独自のBabelのオプションを設定する方法を紹介する記事です。

Node.jsで書かれたサーバーサイド用のテストとReactで書かれたフロントエンド用のテストでBabelの設定を変更したいために調べた内容です。他にも方法があれば教えていただけると助かります。

今回の記事ではReactのテストを例にしていますが、他のフレームワークやライブラリにも適応できます。


JestでBabelを使う

まずはじめにJestは設定をJavaScriptで書くことができます。

ファイル名をjest.config.jsにしておくか、Jestを実行するときに--config <path/to/file>のように--configオプションをつけて設定ファイルを指定することができます。

JestでBabelを使ってテストを実行するためにはbabel-jestというパッケージが必要です。

以下はReactのテストを実行するための最小の設定です。コードはclientというディレクトリにある想定です。

ここで注目すべきは"transform"です。ここでbabel-jestを指定することでJestの実行時にBabelを使います。

今回はReact用にJestを設定する例をとるため、jest.config.react.jsという名前にします。(名前は任意のため何でも良い)


jest.config.react.js

module.exports = {

"testMatch": [
"<rootDir>/client/__tests__/**/*.test.js",
],
"moduleFileExtensions": [
"js",
"jsx",
],
"moduleDirectories": [
"node_modules",
"client",
],
"transform": {
"^.+\\.jsx?$": "babel-jest",
}
};



babel-jestにBabelの設定を指定する

babel-jestですが、デフォルトではプロジェクト内の.babelrcに書かれたBabelの設定を使います。

しかし、前述のとおりフロントエンドとサーバーサイドで別のBabelの設定で実行したいため、できれば.babelrcをいじりたくはありません。

そういった時のためにbabel-jestにはcreateTransformerというAPIが用意されています。このAPIを使うことでJestの実行時に使うBabelの設定を指定することができます。

まず、Babelの設定ファイルを用意します。babelrcfalseにすることを忘れないようにしてください。


custom-transformer.js

const babelJest = require("babel-jest");

const babelOptions = {
presets: [
["@babel/env", {
"targets": {
"node": "current",
},
"exclude": ["transform-regenerator"],
}],
"@babel/react",
],
babelrc: false,
};
module.exports = babelJest.createTransformer(babelOptions);


次に前述で出てきたJestの設定ファイル内の"transorm"の値を上記のBabelの設定ファイルのパスに変更します。


jset.config.react.js

module.exports = {

"testMatch": [
"<rootDir>/client/__tests__/**/*.test.js",
],
"moduleFileExtensions": [
"js",
"jsx",
],
"moduleDirectories": [
"node_modules",
"client",
],
"transform": {
- "^.+\\.jsx?$": "babel-jest",
+ "^.+\\.jsx?$": "path/to/custom-transformer.js",
}
};

ここで上記のcustom-transformer.jsを作らずに以下のように直接Babelの設定オブジェクトを"transorm"の値に設定すればいいのではないかと思うかもしれませんが、TypeError: customJSTransformer.includes is not a functionとエラーになります。

module.exports = {

"testMatch": [
"<rootDir>/client/__tests__/**/*.test.js",
],
"moduleFileExtensions": [
"js",
"jsx",
],
"moduleDirectories": [
"node_modules",
"client",
],
"transform": {
"^.+\\.jsx?$": {
presets: [
["@babel/env", {
"targets": {
"node": "current",
},
"exclude": ["transform-regenerator"],
}],
"@babel/react",
],
babelrc: false,
}
}
};

Issueもありますが、上記のようにBabelの設定ファイルを別で分けておくしか解決方法はなさそうです。

Jest-babel createTransformer Error: customJSTransformer.includes is not a function · Issue #7015 · facebook/jest · GitHub

自分は最初"transform"に直接Babelの設定を書いててエラーになりました。もしかするとこのIssueが閉じられるころには修正されているかもしれませんが、現時点(2019/03/11時点)ではこのエラーは発生します。そのため、Babelの設定は分けてください。


Jestを実行

JestとBabelの設定はできたのでjest --config jest.config.react.jsを実行すると、custom-transform.jsにて設定したBabelの設定を使ってJestを実行することができます。


参考

最後までお読みいただきありがとうございました。不備や質問はコメント欄またはTwitterにメンションしてもらえると助かります。