フロントエンドの戦場へようこそ。
`tsconfig.json` の `jsx` オプション、何気なく `react-jsx` を選んで終わらせていないか? それはそれで現代の最適解の一つだが、大規模なプロジェクトになればなるほど、フレームワークの裏側で何が起きているのかを知らないと、思わぬ型エラーやバンドルサイズの肥大化に足元をすくわれることになる。
今日は、TypeScriptの `jsx` 関連の設定を深掘りし、React、Vue、SolidJSという現代の主要プレイヤーたちが、どうやってあの「JSXという名の糖衣構文」をJavaScriptに変換しているのか、その裏側のロジックを叩き込む。
—
JSXオプションの「今」を知る
まず前提として、今のTypeScriptにおける `jsx` オプションは、単なる「変換の有無」を決めるだけではない。「JSXの呼び出し先」をどこにするかを決める設定だ。
1. `jsx: “react-jsx”` (モダンReactの標準)
React 17以降、`React.createElement` を手動でインポートする必要がなくなったのは、この設定のおかげだ。TypeScriptは自動的に `_jsx` 関数をインポートしてくれる。
{
“compilerOptions”: {
“jsx”: “react-jsx”, // 自動的にReactのランタイムを呼び出す
“jsxImportSource”: “react” // どこからインポートするか
}
}
2. `jsx: “react-jsxdev”` (開発用)
デバッグ情報を付与するモードだ。開発中に `_jsxDEV` を呼び出し、コンポーネントのソース位置情報などをReact DevToolsに伝える。本番環境では決して使わないように。
3. `jsx: “react”` (レガシー)
`React.createElement` を直接呼び出す古い方式。未だにレガシーなライブラリとの互換性が必要なプロジェクトでは現役だが、基本的には避けるべきだ。
—
現場で差が出る「jsxImportSource」の魔法
中級者から一歩先へ行くために理解しておくべきなのが、`jsxImportSource` の概念だ。React以外、例えばVueやSolidJSを使う場合、この設定が生命線になる。
SolidJSの場合
SolidJSはReactと違い、コンポーネントを再レンダリングしない。そのため、JSXをコンパイルする際も `solid-js` のランタイムを指定する必要がある。
{
“compilerOptions”: {
“jsx”: “react-jsx”,
“jsxImportSource”: “solid-js”, // ここを書き換えるだけでSolidJS用になる
“jsxFactory”: “h”, // 必要に応じて指定
“jsxFragmentFactory”: “Fragment”
}
}
なぜこれが重要なのか?
`jsxImportSource` を適切に設定することで、TypeScriptは「JSXを見つけたときに、どこから関数をインポートすればいいか」を理解する。もしここを間違えると、`’h’ is not defined` といった、初心者が必ず一度は踏むエラーに見舞われることになる。
—
実践:フレームワーク別の `tsconfig.json` 構成案
現場でそのまま使える、フレームワーク別の「正解パターン」を置いておく。
パターンA:モダンReact (Vite + React)
{
“compilerOptions”: {
“jsx”: “react-jsx”,
“jsxImportSource”: “react”,
“target”: “ESNext”,
“moduleResolution”: “bundler” // バンドラベースのモダンな解決
}
}
パターンB:Vue 3 (JSX使用時)
Vueは通常テンプレートを使うが、JSXを使う場合は `@vue/babel-plugin-jsx` が主流。しかし、TypeScriptだけで完結させたいならこうだ。
{
“compilerOptions”: {
“jsx”: “preserve”, // TS側では変換せず、Babelに任せるのがVueの定石
“jsxImportSource”: “vue”
}
}
※補足:Vueの場合はTSの変換よりもBabelを通すのが一般的だ。ビルドパイプラインの構成に注意せよ。
—
現場のシニアからのアドバイス:泥臭いTips
最後に、現場で「なぜか動かない」を防ぐための生存戦略を2つ授ける。
1. `jsxFactory` と `jsxFragmentFactory` の役割を理解せよ
`jsxImportSource` はランタイム(React 17以降)向けだが、もし自前で仮想DOMライブラリを組んだり、軽量なJSXパーサを使う場合は、`jsxFactory` で生成関数(`h`など)を明示的に指定する必要がある。これらはセットで覚えること。
2. `@types/react` との戦い
Reactのバージョンと `@types/react` のバージョンがズレていると、`jsxImportSource` をいじっても型定義がコンフリクトすることがある。`npm list @types/react` でバージョンを確認し、プロジェクトのReact本体と必ず整合性を取れ。
まとめ
JSXの設定は、単なる設定ファイルの一部ではない。フレームワークがDOMをどう構築するかという「哲学」をTypeScriptに教え込む行為だ。
- 基本は `react-jsx` を使う。
- React以外なら `jsxImportSource` を指定する。
- 変換がうまくいかない時は `jsx: “preserve”` にして、ビルドツール(esbuildやBabel)に変換を任せているか疑え。
この挙動を理解していれば、どんなフレームワークが現場に投入されても、環境構築で時間を溶かすことはなくなるはずだ。さあ、エディタに戻ってコードを書き殴れ。

コメント