Babel で JSX が「Support for the experimental syntax 'jsx' isn't currently enabled」になる
JSX を含むファイルを変換しようとして構文エラーになるのは、Babel に JSX を読ませるプリセットが入っていないため。
@babel/preset-react を追加して設定ファイルの presets に登録すると解消する。
公開:
要約
Support for the experimental syntax 'jsx' isn't currently enabled は、Babel が <div /> のような JSX を JavaScript の構文として解釈できないときに出ます。
Babel は既定では JSX を知らないので、構文プラグインを含む @babel/preset-react を明示的に読ませる必要があります。
npm i -D @babel/preset-react// babel.config.json
{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}よくある原因
- プリセットが未インストール:
@babel/preset-reactにはsyntax-jsx/transform-react-jsx/transform-react-display-nameの 3 プラグインが含まれる。
これが無いと構文解析の段階で落ちる。 - インストールしたが登録していない:
package.jsonの devDependencies には入っているのに、presets配列へ足していないケースが多い。
エラーメッセージは「インストールされていない」ではなく「有効になっていない」と言っている。 - 設定ファイル自体が読まれていない: モノレポや
node_modulesのファイルを対象にすると.babelrcは届かない。
詳しくは /babel/babelrc-not-applied/ を参照。 - ツールごとに設定が分かれている: Jest は
babel-jestを通すのでbabel.config.jsonを読むが、webpack のbabel-loaderにoptionsを直書きしていると設定が二重管理になり、片方だけ JSX を有効にしていることがある。
解決策
1. preset-react を入れて presets に登録する
presets の並びは後ろから前へ適用されるため、preset-env と併記する順序は上の例のままで問題ありません。
// babel.config.json
{
"presets": [
["@babel/preset-env", { "targets": { "node": "current" } }],
"@babel/preset-react"
]
}2. TypeScript の .tsx なら preset-typescript も足す
型注釈と JSX は別のプリセットが担当します。.tsx を扱うなら両方必要です。
// babel.config.json
{
"presets": [
"@babel/preset-env",
"@babel/preset-react",
["@babel/preset-typescript", { "isTSX": true, "allExtensions": true }]
]
}3. 適用された設定を出力して確かめる
設定ファイルが読まれていない場合、プリセットを足しても状況は変わりません。
対象ファイルに実際に適用された設定を表示します。
npx babel --show-config src/App.jsx出力の presets に @babel/preset-react が出てこなければ、設定ファイルの置き場所か root 指定の問題です。
4. runtime の既定値を踏まえて import を整理する
@babel/preset-react の runtime オプションは v7.9.0 以降 automatic が既定です。
JSX の変換に必要な関数は自動で import されるため、各ファイルの先頭に React を読み込む記述は不要になります。
古い設定を引き継いで classic を明示している場合は、React の import が無いと実行時に落ちます。
// babel.config.json
{
"presets": [["@babel/preset-react", { "runtime": "automatic" }]]
}