EY-Office ブログ

tsconfig.jsonのjsx項目を調べてみた

ある仕事でHTMLメール作成にReactが使えないか調べた際に、TypeScriptからJavaScriptへの変換で使われる設定ファイルtsconfig.jsonjsx項目(属性)の詳細を調べてみました。

普段はcreate-next-appが作るデフォルトのtsconfig.jsonを使っていますが、調べてみると思わぬ事を知りました。

jsx-item-in-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.createElementReact.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()は微妙に異なるようです😅
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)() などを知る事ができました。

たまには設定ファイルの調査も、おもしろいですね !?

- about -

EY-Office代表取締役
・プログラマー
吉田裕美の
開発者向けブログ