設定ファイル
設定ファイルの種類
Babelには、併用または個別に使用できる2つの並列設定ファイル形式があります。
履歴
バージョン | 変更点 |
---|---|
v7.21.0 | .babelrc.cts とbabel.config.cts のサポート(実験的) |
v7.8.0 | .babelrc.mjs とbabel.config.mjs のサポート |
v7.7.0 | .babelrc.json 、.babelrc.cjs 、babel.config.json 、babel.config.cjs のサポート |
- プロジェクト全体の構成
- 以下の拡張子を持つ
babel.config.*
ファイル:.json
、.js
、.cjs
、.mjs
、.cts
。
- 以下の拡張子を持つ
- ファイル相対の構成
- 以下の拡張子を持つ
.babelrc.*
ファイル:.json
、.js
、.cjs
、.mjs
、.cts
。 - 拡張子なしの
.babelrc
ファイル。 "babel"
キーを持つpackage.json
ファイル。
- 以下の拡張子を持つ
プロジェクト全体の構成
Babel 7.xの新機能として、Babelには"ルート"ディレクトリという概念があり、デフォルトでは現在の作業ディレクトリになります。プロジェクト全体の構成では、Babelは自動的にこのルートディレクトリ内でbabel.config.json
ファイル、またはサポートされている拡張子を使用した同等のファイルを検索します。あるいは、ユーザーは明示的な"configFile"値を使用して、デフォルトの設定ファイル検索動作を上書きできます。
プロジェクト全体の構成ファイルは、構成ファイルの物理的な場所から分離されているため、広範囲に適用する必要がある構成に最適です。これにより、プラグインとプリセットは、従来のBabel 6.xでは構成が非常に困難だったnode_modules
やシンボリックリンクされたパッケージ内のファイルにも簡単に適用できます。
このプロジェクト全体の構成の主な欠点は、作業ディレクトリに依存するため、作業ディレクトリがモノレポのルートでない場合、モノレポでは使用が困難になる可能性があることです。そのコンテキストでの設定ファイルの使用例については、モノレポのドキュメントを参照してください。
"configFile"をfalse
に設定することで、プロジェクト全体の構成を無効にすることもできます。
ファイル相対の構成
Babelは、コンパイルされる"filename"から始まるディレクトリ構造を上向きに検索して(下記の注意点に制限されます)、サポートされている拡張子を使用した同等のファイルと共に.babelrc.json
ファイルをロードします。これは、パッケージのサブセクションに独立した構成を作成できるため、強力な機能です。ファイル相対の構成は、プロジェクト全体の構成値の上位にマージされるため、特定の上書きに役立つ可能性がありますが、"overrides"でも実現できます。
ファイル相対の設定を使用する際のいくつかの特殊なケースを考慮する必要があります。
package.json
を含むディレクトリが見つかると検索が停止するため、相対的な構成は単一のパッケージ内でのみ適用されます。- コンパイルされる"filename"は、"babelrcRoots"パッケージの内側に存在する必要があります。そうでない場合、検索は完全にスキップされます。
これらの注意点から、
.babelrc.json
ファイルは、それ自身のパッケージ内のファイルのみに適用されます。- Babelの「ルート」ではないパッケージ内の
.babelrc.json
ファイルは、"babelrcRoots"でオプトインしない限り無視されます。
多数のパッケージを持つモノレポの構成方法の詳細については、モノレポのドキュメントを参照してください。 "babelrc"をfalse
に設定することで、ファイル相対の設定を無効にすることもできます。
6.xと7.xの.babelrc
の読み込み
Babel 6.xからのユーザーは、Babel 7.xの新機能であるこれらの2つの特殊なケースで問題に遭遇する可能性があります。これらの2つの制限は、Babel 6.xの一般的な問題に対処するために追加されました。
.babelrc
ファイルがnode_modules
依存関係に適用され、多くの場合予期せず適用される。.babelrc
ファイルが、人々が通常の依存関係のように動作することを期待していた場合、シンボリックリンクされたnode_modules
に適用されなかった。node_modules
依存関係内の.babelrc
ファイルが検出されるが、内部のプラグインとプリセットは一般的にインストールされておらず、ファイルをコンパイルするBabelのバージョンで有効ではない可能性がある。
これらのケースは、主にモノレポ構造のユーザーに問題を引き起こします。なぜなら、
.babelrc
packages/
mod1/
package.json
src/index.js
mod2/
package.json
src/index.js
構成はパッケージの境界を越えているため、完全に無視されます。
代替案としては、"extends"を以下のように使用する各サブパッケージに.babelrc
を作成することです。
{ "extends": "../../.babelrc" }
残念ながら、このアプローチはやや反復的になり、Babelの使用方法によっては、"babelrcRoots"の設定が必要になる可能性があります。
そのため、.babelrc
の名前をプロジェクト全体の"babel.config.json"に変更する方が望ましい場合があります。上記のプロジェクト全体のセクションで説明したように、作業ディレクトリが正しくない場合、Babelは設定ファイルを見つけられないため、"configFile"を明示的に設定する必要がある場合があります。
サポートされているファイル拡張子
Babelは、設定ファイルの種類のセクションで説明されているように、Node.jsがネイティブにサポートする任意のファイル拡張子を使用して構成できます。
-
babel.config.json
と.babelrc.json
はJSON5として解析され、Babelが受け入れるオプション形式に一致するオブジェクトを含める必要があります。これらはv7.7.0
からサポートされています。可能な限りこのファイルの種類を使用することをお勧めします。JS設定ファイルは、ビルド時に条件付きまたは計算される複雑な設定がある場合に便利です。ただし、欠点は、JS設定ファイルは静的解析が困難なため、キャッシュ可能性、リント、IDEのオートコンプリートなどに悪影響を与えることです。
babel.config.json
と.babelrc.json
は静的なJSONファイルであるため、バンドラーなどのBabelを使用する他のツールがBabelの結果を安全にキャッシュできます。これは、ビルドのパフォーマンスを大幅に向上させることができます。 -
babel.config.cjs
と.babelrc.cjs
を使用すると、module.exports
を使用してCommonJSとして構成を定義できます。これらはv7.7.0
からサポートされています。 -
babel.config.mjs
と.babelrc.mjs
は、ネイティブのECMAScriptモジュールを使用します。これらはNode.js 13.2以降(または--experimental-modules
フラグを使用した古いバージョン)でサポートされています。ネイティブのECMAScriptモジュールは非同期であることを忘れないでください(そのため、import()
は常にPromiseを返します)。このため、.mjs
設定ファイルは、Babelを同期的に呼び出すと例外をスローします。これらはv7.8.0
からサポートされています。 -
babel.config.js
と.babelrc.js
は、package.json
ファイルに"type": "module"
オプションが含まれている場合、.mjs
と同等に動作し、それ以外の場合は.cjs
ファイルとまったく同じです。 -
babel.config.cts
と.babelrc.cts
を使用すると、Typescript + CommonJSとして構成を定義できます。@babel/preset-typescript
をインストールするか、ts-node
を使用してBabelを実行する必要があります。注記🚧 この機能は実験的です。Node.js ESMローダーAPIの安定化を待つため、現時点では
babel.config.ts
とbabel.config.mts
ファイルを使用することはできません。
JavaScript設定ファイルは、オブジェクトをエクスポートするか、呼び出されると生成された設定を返す関数をエクスポートできます。関数から返す設定には、Babel自体によって公開されるAPIにアクセスできるため、いくつかの特別な権限が与えられます。詳細については、設定関数APIを参照してください。
互換性のため、.babelrc
は.babelrc.json
のエイリアスです。
モノレポ
モノレポ構造のリポジトリは通常多くのパッケージを含んでいるため、ファイル相対設定および一般的な設定ファイルの読み込みで言及されている注意点によく遭遇します。このセクションでは、モノレポの設定へのアプローチ方法を理解するのに役立つ情報を提供します。
モノレポ設定では、Babelが作業ディレクトリを論理的な"ルート"として扱うことを理解することが重要です。これは、Babelをリポジトリ全体に適用することなく、特定のサブパッケージ内でBabelツールを実行したい場合に問題を引き起こします。
.babelrc.json
ファイルを使用するか、中央のbabel.config.json
のみを使用するかの決定も重要です。.babelrc.json
ファイルは、Babel 6のようにサブフォルダー固有の設定に必須ではなく、多くの場合、Babel 7ではbabel.config.json
の方が好まれます。
ルートbabel.config.json
ファイル
モノレポ構造における最初のステップは、リポジトリルートにbabel.config.json
ファイルを作成することです。これにより、リポジトリのベースディレクトリというBabelの中核概念が確立されます。.babelrc.json
ファイルを使用して個々のパッケージを設定する場合でも、リポジトリレベルのオプションのための場所として持つことが重要です。
多くの場合、リポジトリ設定全体をルートのbabel.config.json
に配置できます。"overrides"を使用すると、リポジトリの特定のサブフォルダーにのみ適用される設定を簡単に指定でき、リポジトリ全体に多数の.babelrc.json
ファイルを作成するよりも分かりやすい場合があります。
最初に遭遇する可能性のある問題は、デフォルトではBabelが"ルート"として設定されているディレクトリからbabel.config.json
ファイルの読み込みを期待することです。つまり、babel.config.json
を作成しても、個々のパッケージ内でBabelを実行すると(例:
cd packages/some-package;
babel src -d dist
そのコンテキストで使用されている"ルート"は、モノレポリポジトリのルートではなく、babel.config.json
ファイルが見つかりません。
ビルドスクリプトがすべてリポジトリルートを基準にして実行される場合、既に動作しているはずです。しかし、サブパッケージ内からBabelコンパイルプロセスを実行する場合は、Babelに設定ファイルの場所を指示する必要があります。これにはいくつかの方法がありますが、推奨される方法は、"upward"
を使用した "rootMode" オプションです。これにより、Babelは作業ディレクトリから上方向にbabel.config.json
ファイルを検索し、その場所を"ルート"値として使用します。
設定が検出されているかどうかをテストするのに役立つ方法の1つは、それがbabel.config.json
のJavaScriptファイルである場合、console.log()
呼び出しを配置することです。ログは、Babelが最初に読み込むときに実行されます。
この値の設定方法はプロジェクトによって異なりますが、いくつかの例を以下に示します。
CLI
babel --root-mode upward src -d lib
@babel/register
require("@babel/register")({
rootMode: "upward",
});
Webpack
module: {
rules: [
{
loader: "babel-loader",
options: {
rootMode: "upward",
},
},
];
}
Jest
Jestは多くの場合、モノレポのルートにインストールされ、設定が必要ない場合がありますが、パッケージごとにインストールされている場合は、設定が複雑になる可能性があります。
主な部分は、オプションを設定するためにbabel-jest
のデフォルトの動作をラップするカスタムのJestトランスフォーマーファイルを作成することです(例:
module.exports = require("babel-jest").default.createTransformer({
rootMode: "upward",
});
これを保存したら、transformオプションを介してJestのオプションでbabel-jest
の代わりにそのファイルを使用します。
"transform": {
"^.+\\.jsx?$": "./path/to/wrapper.js"
},
そのため、すべてのJSファイルは、オプションが有効になっているバージョンのbabel-jest
で処理されます。
babel-jest
< 27を使用する場合は、.default
部分を省略する必要があります: require("babel-jest").createTransformer({ ...
。
その他
多くのツールがありますが、本質的には、作業ディレクトリが既にモノレポのルートでない場合、rootMode
オプションを有効にする必要があります。
サブパッケージ.babelrc.json
ファイル
babel.config.json
ファイルが"ルート"にある必要があるのと同じように、.babelrc.json
ファイルはデフォルトでルートパッケージに存在する必要があります。これは、作業ディレクトリがbabel.config.json
の読み込みに影響を与えるのと同じように、.babelrc.json
の読み込みにも影響を与えることを意味します。
上記で説明したように、babel.config.json
ファイルが正しく読み込まれていると仮定すると、Babelはルートパッケージ内(サブパッケージ内ではない)の.babelrc.json
ファイルのみを処理します。たとえば、
package.json
babel.config.js
packages/
mod/
package.json
.babelrc.json
index.js
packages/mod/index.js
ファイルをコンパイルしても、この.babelrc.json
はルートパッケージではなくサブパッケージ内にあるため、packages/mod/.babelrc.json
は読み込まれません。
この.babelrc.json
の処理を有効にするには、babel.config.json
ファイル内から"babelrcRoots"オプションを使用して、
babelrcRoots: [
".",
"packages/*",
],
Babelが、元のレポジトリルートとともに、すべてのpackages/*
パッケージを.babelrc.json
ファイルの読み込みが許可されるパッケージとして認識するようにします。
設定関数API
JS設定ファイルは、設定関数APIに渡される関数をエクスポートできます。
module.exports = function(api) {
return {};
};
api
オブジェクトは、Babel自身がインデックスモジュールから公開するすべてのものと、設定ファイル固有のAPIを公開します。
api.version
型: string
設定ファイルを読み込んでいるBabelのバージョンのバージョン文字列です。
api.cache
JS設定は、設定を動的に計算できるため優れていますが、欠点はキャッシングが難しくなることです。Babelは、ファイルがコンパイルされるたびに設定関数を再実行することを避けたいと考えています。なぜなら、そうすると、その設定で参照されているすべてのプラグインとプリセット関数を再実行する必要も生じるからです。
これを回避するために、Babelは、設定ファイル内でキャッシングを管理する方法を設定関数ユーザーに指示することを期待しています。
api.cache.forever()
- 計算された設定を永続的にキャッシュし、関数を二度と呼び出しません。api.cache.never()
- この設定をキャッシュせず、毎回関数を再実行します。api.cache.using(() => process.env.NODE_ENV)
-NODE_ENV
の値に基づいてキャッシュします。using
コールバックが期待される値とは異なる値を返すたびに、全体の設定関数が再度呼び出され、キャッシュに新しいエントリが追加されます。api.cache.invalidate(() => process.env.NODE_ENV)
-NODE_ENV
の値に基づいてキャッシュします。using
コールバックが期待される値とは異なる値を返すたびに、全体の設定関数が再度呼び出され、キャッシュ内のすべてエントリが結果で置き換えられます。api.cache(true)
-api.cache.forever()
と同じです。api.cache(false)
-api.cache.never()
と同じです。
実際のコールバックの結果を使用してキャッシュエントリの有効性を確認するため、
- コールバックは小さく、副作用のないものであることが推奨されます。
- コールバックは、可能な限り最小の範囲の値を返す必要があります。たとえば、上記の
.using(() => process.env.NODE_ENV)
の使用は理想的ではありません。これは、検出されたNODE_ENV
の値の数に応じて、不明な数のキャッシュエントリが作成されるためです。.using(() => process.env.NODE_ENV === "development")
の方が安全です。キャッシュエントリはtrue
またはfalse
のいずれかしかありません。
api.env(...)
NODE_ENV
は動作を切り替えるための一般的な方法であるため、Babelにはそれ専用のAPI関数も含まれています。このAPIは、Babelが読み込まれた"envName"を確認するための簡単な方法として使用され、他のオーバーライド環境が設定されていない場合、NODE_ENV
を考慮します。
いくつかの異なる形式があります。
api.env("production")
は、envName === "production"
の場合にtrue
を返します。api.env(["development", "test"])
は、["development", "test"].includes(envName)
の場合にtrue
を返します。api.env()
は、現在のenvName
文字列を返します。api.env(envName => envName.startsWith("test-"))
は、envが"test-"で始まる場合にtrue
を返します。
この関数は、Babelが特定のenvName
に依存するビルドを認識できるようにするために、上記で説明したapi.cache
を内部的に使用します。api.cache.forever()
またはapi.cache.never()
と一緒に使用しないでください。
api.caller(cb)
このAPIは、Babelに渡されたcaller
データにアクセスする方法として使用されます。多くのBabelインスタンスが異なるcaller
値で同じプロセスで実行される可能性があるため、このAPIはapi.env()
と同じように、api.cache
を自動的に設定するように設計されています。
caller
値は、コールバック関数の最初の引数として使用できます。次のようなものと併用するのが最適です。
function isBabelRegister(caller) {
return !!(caller && caller.name === "@babel/register");
}
module.exports = function(api) {
const isRegister = api.caller(isBabelRegister);
return {
// ...
};
};
特定の環境に基づいて設定動作を切り替えるため。
api.assertVersion(range)
api.version
は一般的に有用ですが、バージョンを宣言するだけのシンプルな方法も時には便利です。
module.exports = function(api) {
api.assertVersion("^7.2");
return {
// ...
};
};