Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

この記事は.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にメンションしてもらえると助かります。

shisama
Node.js Core Collaborator. 関西Node学園Organizer.
https://shisama.dev
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away