できない.dev

Babel で @babel/plugin-proposal-* が見つからない

Babel の @babel/plugin-proposal-* が見つからないなら、設定と依存を plugin-transform-* に置き換えれば直る。
Babel 7.22.0 で改名され、旧名は更新が止まっている。

公開: 更新:

症状できない · exit 1
npx babel src/index.js > /dev/null 2>&1
解決後できた · exit 0
npx babel src/index.js
…
function _toPrimitive(t, e) { if ("object" != typeof t || !t) return t; var r; if ("undefined" != typeof Symbol && void 0 !== (r = t[Symbol.toPrimitive])) { var i = r.call(t, e || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === e ? String : Number)(t); }
class Counter {
  constructor() {
    _defineProperty(this, "count", 0);

2026-10-21 に node:20(Babel 7.29.7 / Node.js 20.20.2) で実際に打って取った出力。検証環境の詳細

要約

次のようなエラーで止まるのは、そのプラグインが改名されたためだ(/path/to/project の部分はプロジェクトのディレクトリ。@babel/core 7.22.0・7.24.0・7.26.0・7.29.7 の npx babel で確認)。

Error: Cannot find package '@babel/plugin-proposal-class-properties' imported from /path/to/project/babel-virtual-resolve-base.js

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

実行例

実際に上記の手順を node:20(Babel 7.29.7)で動かすと、設定に @babel/plugin-proposal-class-properties を残したままでは Cannot find package のエラーで終了コード 1 になった。plugin-transform- に書き換えるとクラスフィールドが _defineProperty に変換されて終了コード 0 で通り、プラグインの個別指定をやめて @babel/preset-env の targets を defaults にした場合は、クラスフィールドがそのまま残る形で終了コード 0 になった。

$ npx babel --version
7.29.7 (@babel/core 7.29.7)
$ npx babel src/index.js 2>&1 | head -n 1
Error: Cannot find package '@babel/plugin-proposal-class-properties' imported from /tmp/tmp.4m0CCqStZj/babel-virtual-resolve-base.js
$ npx babel src/index.js > /dev/null 2>&1
$ echo $?
1
$ sed -i s/plugin-proposal-class-properties/plugin-transform-class-properties/ babel.config.json
$ cat babel.config.json
{
  "presets": [["@babel/preset-env", { "targets": { "node": "current" } }]],
  "plugins": ["@babel/plugin-transform-class-properties"]
}
$ npm install -D @babel/plugin-transform-class-properties --no-audit --no-fund
up to date in 251ms
$ npx babel src/index.js
"use strict";
 
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, e) { if ("object" != typeof t || !t) return t; var r; if ("undefined" != typeof Symbol && void 0 !== (r = t[Symbol.toPrimitive])) { var i = r.call(t, e || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === e ? String : Number)(t); }
class Counter {
  constructor() {
    _defineProperty(this, "count", 0);
  }
  inc() {
    this.count += 1;
    return this.count;
  }
}
console.log(new Counter().inc());
$ echo $?
0
$ npx babel src/index.js
"use strict";
 
class Counter {
  count = 0;
  inc() {
    this.count += 1;
    return this.count;
  }
}
console.log(new Counter().inc());
$ echo $?
0
$ BABEL_SHOW_CONFIG_FOR=src/index.js npx babel src/index.js
Babel configs on "/tmp/tmp.4m0CCqStZj/src/index.js" (ascending priority):
config /tmp/tmp.4m0CCqStZj/babel.config.json
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": "defaults"
      }
    ]
  ]
}
 
programmatic options from @babel/cli
{
  "sourceFileName": "src/index.js",
  "caller": {
    "name": "@babel/cli",
    "supportsStaticESM": false,
    "supportsDynamicImport": false,
    "supportsExportNamespaceFrom": false
  },
  "filename": "src/index.js"
}
-----End Babel configs-----
"use strict";
 
class Counter {
  count = 0;
  inc() {
    this.count += 1;
    return this.count;
  }
}
console.log(new Counter().inc());

— 2026-10-21 時点の出力

検証環境Node.js 20.20.2 / npm 10.8.2 / Python 3.11.2 / 2026-10-21 検証(ほか 2 件)
検証日
実行環境
node:20 Debian GNU/Linux 12 (bookworm)
バージョン
  • Node.js 20.20.2
  • npm 10.8.2
  • Python 3.11.2
  • Git 2.39.5
  • Babel 7.29.7

この記事の「実行例」は、上記の環境で実際にコマンドを実行して得られた出力をそのまま掲載しています。 再現手順はリポジトリの検証スクリプトとして管理し、定期的に再実行して出力を更新しています。

解決策

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. 適用された設定を表示して確かめる

複数の設定ファイルが重なっていると、直したつもりのファイルが読まれていないことがある。

BABEL_SHOW_CONFIG_FOR=src/index.js npx babel src/index.js

出力に旧名が残っていれば、別の設定ファイルが効いている。
設定ファイルの探索順は /babel/babelrc-not-applied/ を参照のこと。

なお、まだ標準化されていない構文(デコレータなど)のプラグインは plugin-proposal- のままである。
すべてを一括置換すると、今度はそちらが見つからなくなる。

よくある原因

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