esbuild「The JSX syntax extension is not currently enabled」の原因と直し方
esbuild の The JSX syntax extension is not currently enabled は、.js のファイルに JSX を書くと出る。
拡張子を .jsx にするか、--loader:.js=jsx で .js を JSX として読ませれば直る。
公開:
要約
esbuild は拡張子でローダーを選び、.js には JSX を読まない js ローダーを使う。
そのため .js のファイルに JSX を書いてバンドルすると、esbuild 0.28.2 では次の表示になり、終了コード 1 で止まった。
✘ [ERROR] The JSX syntax extension is not currently enabled
src/app.js:2:24:
2 │ function App() { return <h1>hello</h1>; }
╵ ^
The esbuild loader for this file is currently set to "js" but it must be set to "jsx" to be able to parse JSX syntax. You can use "--loader:.js=jsx" to do that.ファイル名を .jsx にするか、--loader:.js=jsx を付ければ直る。
エラーの最後の行も同じ指定を案内している。
解決策
1. 拡張子を変えるか、.js のローダーを jsx にする
mv src/app.js src/app.jsx
npx esbuild src/app.jsx --bundle --outfile=out.jsファイル名を変えたくないときは、.js を JSX として読ませる。
npx esbuild src/app.js --bundle --loader:.js=jsx --outfile=out.jsどちらも終了コード 0 で通った。
ビルドスクリプトで JavaScript API を使っているなら、loader に同じ指定を書く。
await esbuild.build({
entryPoints: ["src/app.js"],
bundle: true,
outfile: "out.js",
loader: { ".js": "jsx" },
});2. 標準入力なら --loader=jsx を付ける
echo 'const a = <div/>;' | npx esbuild --loader=jsx標準入力には拡張子が無いので、ローダーを 1 つだけ指定する形になる。
3. 依存パッケージの .js も同じ指定で読める
--loader:.js=jsx はバンドルに含まれるすべての .js に効く。node_modules の中の JSX で止まっていたバンドルも、この指定を足すと通った。
4. 通った後に React is not defined が出る場合
esbuild の既定の変換は JSX を React.createElement(...) に書き換える。
ファイルで React を import していないと、ビルドは通っても実行時に ReferenceError: React is not defined になった。
各ファイルで import するか、--jsx=automatic を付けて JSX の実行時ライブラリを esbuild に読み込ませる。
npx esbuild src/app.jsx --bundle --jsx=automatic --outfile=out.jsよくある原因
- JSX を
.jsに書いている。
Create React App などから移ってきたプロジェクトは.jsに JSX を書いていることが多く、esbuild に替えた時点でこのエラーになる。 - 標準入力からコードを渡している。
echo 'const a = <div/>;' | npx esbuildは<stdin>:1:10を指して同じエラーになった。 - 依存パッケージが JSX を
.jsのまま配布している。
エラーの位置がnode_modules/...を指していれば、自分のコードではなくそのパッケージのファイルが原因である。 tsconfig.jsonのjsxを設定しても、.jsのローダーは変わらない。"jsx": "react-jsx"を置いても同じエラーが出た。