Babel で @babel/plugin-proposal-* が解決できない
標準化が済んだ構文のプラグインは Babel 7.22.0 で @babel/plugin-transform-* に改名された。
旧名のパッケージは更新が止まっているため、設定と依存の両方を新しい名前に置き換える。
公開:
要約
Cannot find module '@babel/plugin-proposal-class-properties' のようなエラーで止まるのは、そのプラグインが改名されたためです。
Babel 7.22.0 で、標準化(Stage 4)が済んだ構文のプラグインは @babel/plugin-proposal-* から @babel/plugin-transform-* へ名前が変わりました。
設定と依存の両方を、新しい名前に置き換えます。
npm uninstall @babel/plugin-proposal-class-properties
npm install -D @babel/plugin-transform-class-propertiesよくある原因
- 改名にともなう解決エラー: Babel 7.22.0 のリリースノートは、Stage 4 に到達した構文のプラグイン 16 個を
plugin-transform-*へ改名したこと、そして「The packages with the old name will no longer be updated.」=旧名のパッケージはもう更新されないことを明記している。
改名対象にはクラスフィールド、プライベートメソッド、オプショナルチェーン、Nullish 合体演算子などが含まれる。 - 設定だけが旧名で残っている: 依存の更新やロックファイルの作り直しで旧パッケージが消え、設定ファイルの記述だけが取り残されるパターン。
エラーは設定を読んだ時点で出る。 - preset-env と役割が重複している: 標準化済みの構文は
@babel/preset-envが対象ブラウザに応じて面倒を見る。
個別指定を残しておく必要はなく、むしろ設定の食い違いを生む。 - 新旧が同居している: 移行の途中で両方が
pluginsに並ぶと、同じ変換が二重に走る。
挙動が読めなくなるので、どちらか片方に寄せる。
解決策
1. 設定ファイルの名前を置き換える
置き換えは機械的です。plugin-proposal- を plugin-transform- にするだけで、オプションの書き方は変わりません。
{
"plugins": [
"@babel/plugin-transform-class-properties",
"@babel/plugin-transform-private-methods",
"@babel/plugin-transform-optional-chaining",
"@babel/plugin-transform-nullish-coalescing-operator"
]
}2. 依存も入れ替える
設定だけ直しても、パッケージが入っていなければ同じエラーが出ます。
npm uninstall @babel/plugin-proposal-class-properties @babel/plugin-proposal-private-methods
npm install -D @babel/plugin-transform-class-properties @babel/plugin-transform-private-methods3. preset-env に寄せて個別指定をやめる
対象ブラウザが決まっているなら、標準化済み構文のプラグインは列挙しないほうが保守が楽です。
{
"presets": [["@babel/preset-env", { "targets": "defaults" }]]
}対象ブラウザの決め方は /babel/preset-env-not-transpiling/ を参照してください。
4. 適用された設定を表示して確かめる
複数の設定ファイルが重なっていると、直したつもりのファイルが読まれていないことがあります。
npx babel --show-config src/index.js出力に旧名が残っていれば、別の設定ファイルが効いています。
設定ファイルの探索順は /babel/babelrc-not-applied/ を参照してください。
なお、まだ標準化されていない構文(デコレータなど)のプラグインは plugin-proposal- のままです。
すべてを一括置換すると、今度はそちらが見つからなくなります。