ある仕事でHTMLメール作成にReactが使えないか調べた際に、TypeScriptからJavaScriptへの変換で使われる設定ファイルtsconfig.jsonのjsx
項目(属性)の詳細を調べてみました。
普段はcreate-next-appが作るデフォルトのtsconfig.json
を使っていますが、調べてみると思わぬ事を知りました。
Bing Image Creatorが生成した画像です
tsconfig.jsonのjsx項目
公式ドキュメントのJSX項目の最初には以下のように書かれています(DeepLで翻訳しました)。
JavaScriptファイルでJSXコンストラクトがどのように出力されるかを制御します。これは、.tsxファイルで開始されたJSファイルの出力にのみ影響します。
react-jsx
:JSXをプロダクション用に最適化された_jsx呼び出しに変更した.jsファイルを出力しますreact-jsxdev
: JSXを開発専用の_jsx呼び出しに変更した.jsファイルを出力しますpreserve
:JSXを変更せずに.jsxファイルを出力するreact-native
:JSXを変更せずに.jsファイルを出力するreact
:React.createElement呼び出しに相当するJSXに変更した.jsファイルを出力する
たくさんの選択肢がありますね。
create-next-appが作ったNext.jsプロジェクトではpreserve
(JSXは変換しない)になっています、JSXをJavaScriptに変換するのはTypeScriptコンパイラーではなく、もっと後のフェーズで行われているんでしょうか?
試してみよう!
jsxの設定でどのようなJavaScriptコードが生成されるのかを見てみましょう。もとになるTypeScriptのコードは以下です。
type HelloProps = {
name: string
};
function Hello({name}: HelloProps) {
return (
<div id="id001">
<p>Hello {name}!</p>
</div>
);
};
preserve
preserve
の場合はJSXは変換されないので、以下のようなJavaScriptのコードが生成されます。
function Hello({ name }) {
return (<div id="id001">
<p>Hello {name}!</p>
</div>);
}
react
react
の場合はcreateElementの説明ページにあるようなコードが生成されています。
__importDefault()
はrequireされたモジュールのメソッド等をdefault
オブジェクトに設定しています。したがってreact_1.default.createElement
はReact.createElement
です- ESモジュールに対応するためにこの関数があるようです
const react_1 = __importDefault(require("react"));
function Hello({ name }) {
return react_1.default.createElement(
"div",
{ id: "id001" },
react_1.default.createElement("p", null, "Hello ", name, "!")
);
}
react-jsx
react-jsx
の場合は以下のようなコードが生成されます。
jsx_runtime_1.jsx()
はReact17で導入された新しい JSX トランスフォームです(知りませんでした😅)(0, jsx_runtime_1.jsx)("div"...)
は何でしょう?(0, jsx_runtime_1.jsx)()
は論理的にはjsx_runtime_1.jsx()
と同じです、カンマ演算子をご存知ない方はMDNのカンマ演算子をみてください- ただしStack overflowによると
(0, func)()
とfunc()
は微妙に異なるようです😅
- ただしStack overflowによると
const jsx_runtime_1 = require("react/jsx-dev-runtime");
function Hello({ name }) {
return (0, jsx_runtime_1.jsx)("div", {
id: "id001",
children: (0, jsx_runtime_1.jsxs)("p", { children: ["Hello ", name, "!"] }),
});
}
react-jsxdev
react-jsxdev
の場合は以下のようなコードが生成されます、ファイル名、行番号などのデバッグ用の情報が付加されてますね。
const jsx_runtime_1 = require("react/jsx-dev-runtime");
function Hello({ name }) {
return (0, jsx_dev_runtime_1.jsxDEV)(
"div",
{
id: "id001",
children: (0, jsx_dev_runtime_1.jsxDEV)(
"p",
{ children: ["Hello ", name, "!"] },
void 0,
true,
{ fileName: _jsxFileName, lineNumber: 10, columnNumber: 7 },
this
),
},
void 0,
false,
{ fileName: _jsxFileName, lineNumber: 8, columnNumber: 11 },
this
);
}
react-native
react-native
の出力コードはpreserve
と同じですが、生成されるファイルは.js
です。React Nativeでは.jsx
は使えないようです。😅
まとめ
普段は気にせずに使っている機能でも、調べてみるとおもしろい機能を持っていたりします。
また、今回は 新しい JSX トランスフォーム や (0, func)() などを知る事ができました。
たまには設定ファイルの調査も、おもしろいですね !?