本文へ移動

設定ファイル

設定ファイルの種類

Babelには、併用または個別に使用できる2つの並列設定ファイル形式があります。

履歴
バージョン変更点
v7.21.0.babelrc.ctsbabel.config.ctsのサポート(実験的)
v7.8.0.babelrc.mjsbabel.config.mjsのサポート
v7.7.0.babelrc.json.babelrc.cjsbabel.config.jsonbabel.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を作成することです。

.babelrc.json
{ "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.tsbabel.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

JavaScript
require("@babel/register")({
rootMode: "upward",
});

Webpack

webpack.config.js
module: {
rules: [
{
loader: "babel-loader",
options: {
rootMode: "upward",
},
},
];
}

Jest

Jestは多くの場合、モノレポのルートにインストールされ、設定が必要ない場合がありますが、パッケージごとにインストールされている場合は、設定が複雑になる可能性があります。

主な部分は、オプションを設定するためにbabel-jestのデフォルトの動作をラップするカスタムのJestトランスフォーマーファイルを作成することです(例:

wrapper.js
module.exports = require("babel-jest").default.createTransformer({
rootMode: "upward",
});

これを保存したら、transformオプションを介してJestのオプションでbabel-jestの代わりにそのファイルを使用します。

jest.config.js
"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"オプションを使用して、

JavaScript
babelrcRoots: [
".",
"packages/*",
],

Babelが、元のレポジトリルートとともに、すべてのpackages/*パッケージを.babelrc.jsonファイルの読み込みが許可されるパッケージとして認識するようにします。

設定関数API

JS設定ファイルは、設定関数APIに渡される関数をエクスポートできます。

JavaScript
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値は、コールバック関数の最初の引数として使用できます。次のようなものと併用するのが最適です。

JavaScript
function isBabelRegister(caller) {
return !!(caller && caller.name === "@babel/register");
}

module.exports = function(api) {
const isRegister = api.caller(isBabelRegister);

return {
// ...
};
};

特定の環境に基づいて設定動作を切り替えるため。

api.assertVersion(range)

api.version は一般的に有用ですが、バージョンを宣言するだけのシンプルな方法も時には便利です。

JavaScript
module.exports = function(api) {
api.assertVersion("^7.2");

return {
// ...
};
};