できない.dev

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

よくある原因

  1. 改名にともなう解決エラー: Babel 7.22.0 のリリースノートは、Stage 4 に到達した構文のプラグイン 16 個を plugin-transform-* へ改名したこと、そして「The packages with the old name will no longer be updated.」=旧名のパッケージはもう更新されないことを明記している。
    改名対象にはクラスフィールド、プライベートメソッド、オプショナルチェーン、Nullish 合体演算子などが含まれる。
  2. 設定だけが旧名で残っている: 依存の更新やロックファイルの作り直しで旧パッケージが消え、設定ファイルの記述だけが取り残されるパターン。
    エラーは設定を読んだ時点で出る。
  3. preset-env と役割が重複している: 標準化済みの構文は @babel/preset-env が対象ブラウザに応じて面倒を見る。
    個別指定を残しておく必要はなく、むしろ設定の食い違いを生む。
  4. 新旧が同居している: 移行の途中で両方が 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-methods

3. 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- のままです。
すべてを一括置換すると、今度はそちらが見つからなくなります。

この記事は役立ちましたか?