Babel の .babelrc が読み込まれず設定が反映されない
.babelrc は package.json が見つかった時点で探索が止まるファイル相対設定のため、別パッケージのファイルには適用されない。
プロジェクト全体に効かせたいときは babel.config.json をルートに置く。
公開:
要約
.babelrc を置いたのにプリセットやプラグインが効かないのは、.babelrc が「ファイル相対設定」で、探索が package.json のあるディレクトリで止まるためです。
公式ドキュメントは「.babelrc files only apply to files within their own package」と明記しています。
つまりモノレポのルートに置いた .babelrc は、packages/* の中のファイルには届きません。
プロジェクト全体に効かせたい設定は、ルートの babel.config.json に書きます。
// babel.config.json(リポジトリのルート)
{
"presets": ["@babel/preset-env"]
}よくある原因
- モノレポのルートに
.babelrcを置いている:packages/app/src/index.jsを変換するとき、Babel はpackages/app/package.jsonを見つけた時点で探索をやめる。
ルートの.babelrcはそもそも読まれない。 node_modulesの中を変換しようとしている: 依存パッケージには自身のpackage.jsonがあるので、こちらの.babelrcは適用されない。
Babel 6 で起きていた「.babelrcが依存パッケージにまで効いてしまう」問題を防ぐための仕様変更である。- 実行時の作業ディレクトリがルートではない:
babel.config.jsonは Babel の「root」(既定ではcwd)から探される。
サブディレクトリでnpm run buildを叩くと、ルートの設定が見つからない。 - 設定ファイルが複数ある:
babel.config.jsonと.babelrcの両方があると、どちらが効いているのか読み違えやすい。
解決策
1. プロジェクト全体の設定は babel.config.json にする
babel.config.json(または babel.config.js)はプロジェクト全体の設定で、パッケージ境界を越えて適用されます。node_modules の中のファイルを変換したい場合も、この形式が必要です。
mv .babelrc babel.config.json2. サブパッケージの .babelrc を明示的に許可する
モノレポで、パッケージごとに .babelrc を持たせたいときは、ルートの babel.config.json で babelrcRoots を指定します。
// babel.config.json
{
"babelrcRoots": [".", "packages/*"]
}これを書かない限り、Babel の root 以外のパッケージにある .babelrc は無視されます。
3. サブディレクトリから実行するなら rootMode を上向きにする
packages/app の中で Babel を動かすと、その場所が root と見なされてルートの babel.config.json が見つかりません。rootMode を upward にすると、上位ディレクトリを遡って設定を探します。
// packages/app/.babelrc
{
"rootMode": "upward"
}upward-optional にすると、見つからなかった場合に現在のディレクトリを root として扱います。
4. 実際に適用された設定を表示して確かめる
推測で直す前に、対象ファイルへ最終的に適用された設定を出力させます。
npx babel --show-config src/index.js読み込まれた設定ファイルのパスと、マージ後のプリセット・プラグインが表示されます。
期待した .babelrc がここに出てこなければ、探索範囲の問題だと確定できます。