作って学ぶ、 JSX (TSX) ランタイムの基本
by
syumai
×
Copy
Open
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Slide 1
Slide 1 text
作って学ぶ、 JSX (TSX) ランタイムの基本 2026-6-6 フロントエンド・PHPカンファレンス北海道2026 @syumai
Slide 2
Slide 2 text
syumai X: @__syumai Website: https://syum.ai © LayerX Inc. whoami LayerX ソフトウェアエンジニア バクラクヘルプデスク エージェントを開発中 Asakusa.go / ECMAScript 仕様輪読会 主催
Slide 3
Slide 3 text
JSXとは?
Slide 4
Slide 4 text
JSXとは? © LayerX Inc. JavaScriptのソースコードの中にXML風の式を書ける拡張記法 ECMAScriptの文法として有効ではない 4
Slide 5
Slide 5 text
JSXはどのように解釈される? ↓変換 © LayerX Inc. Transpilerによって関数呼び出しに変換される 関数名には慣習として h を使うことが多い 5
Slide 6
Slide 6 text
h関数に渡るもの 以下の3つ © LayerX Inc. 名前 属性 子要素 6
Slide 7
Slide 7 text
h関数に渡るもの 以下の3つ © LayerX Inc. 名前 → 文字列 属性 → Object 子要素 → 配列 (可変長引数) 7
Slide 8
Slide 8 text
h関数に渡るもの © LayerX Inc. 8
Slide 9
Slide 9 text
h関数に渡るもの © LayerX Inc. 名前 → "outer" 属性 → { attr1: "attribute 1" } 子要素 → h("inner", ...), h("inner", ...) 9
Slide 10
Slide 10 text
JSXランタイムとは? © LayerX Inc. ここで挙げた「h関数」のような、JSXの式に対応する関数の実装を行い、どのように 振る舞うか決定する機構のことをJSXランタイムと呼ぶ 10
Slide 11
Slide 11 text
JSXランタイムはどこで動く? © LayerX Inc. クライアントサイド (ブラウザ上) だけでなく、サーバーサイドで使うのも一般的 React Server Components、hono-jsx など SSG (静的サイト生成) のユースケースもある ejsなどのテンプレートエンジンを代替する用途だけでも十分便利 11
Slide 12
Slide 12 text
余談
Slide 13
Slide 13 text
h関数の名前の由来は? © LayerX Inc. Vue.jsのドキュメントによると hyperscript 同名の、ほぼ同じインターフェースのライブラリが2012年に開発されていた https://github.com/hyperhype/hyperscript/ Reactは h の名前を使っていない React 17以降は _jsxs および _jsx 、その前は React.createElement Preact、Vue.jsなどの他のJSXランタイムは h の名前を使っている 13
Slide 14
Slide 14 text
https://ja.vuejs.org/guide/extras/render-function © LayerX Inc. 14
Slide 15
Slide 15 text
h関数は何を返せばいい?
Slide 16
Slide 16 text
→ 何を返してもいい!
Slide 17
Slide 17 text
h関数の返す値 © LayerX Inc. Reactなどのイメージで HTML要素 に対応する値を返さないといけない印象がある 実際には 何を返してもいい 文字列 数値 Object etc ... 17
Slide 18
Slide 18 text
例: jsx-slack © LayerX Inc. Slack Block KitのブロックをJSXで組み立てられる 本来は、生のJSONで組む必要がある JSXの式の評価結果として、Slack Block KitのJSONを返す 18
Slide 19
Slide 19 text
例: jsx-slack © LayerX Inc. 生成されるSlack Block KitのJSONの例 https://jsx-slack.netlify.app/ で試せます 19
Slide 20
Slide 20 text
最小のJSXランタイムを作ってみる
Slide 21
Slide 21 text
さっきの例 ↑のh呼び出しの引数を受け取れる関数を書いたらOK! © LayerX Inc. 21
Slide 22
Slide 22 text
完成形
Slide 23
Slide 23 text
最小限のJSXランタイム https://github.com/syumai/minimum-jsx/blob/main/basic-oxc-transform/src/jsxRenderer.js © LayerX Inc. 受け取った値をそのままObjectに詰めて返すだけ 23
Slide 24
Slide 24 text
使ってみる https://github.com/syumai/minimum-jsx/blob/main/basic-oxc-transform/src/index.jsx © LayerX Inc. h 関数をimportして使う ここはTranspilerの設定などによって書き方が変わります 24
Slide 25
Slide 25 text
JSX -> JS変換 https://github.com/syumai/minimum-jsx/blob/main/basic-oxc-transform/scripts/build.mjs © LayerX Inc. 今回はOxc Transformerを使用 昔から一番使われているのはBabel 25
Slide 26
Slide 26 text
変換結果 © LayerX Inc. 意図通りの引数が渡っている! 26
Slide 27
Slide 27 text
実行結果 動いた!🎉 © LayerX Inc. 27
Slide 28
Slide 28 text
型を付ける
Slide 29
Slide 29 text
h関数のTypeScript版 ( type というパラメータ名については温かい目で見てください) © LayerX Inc. 29
Slide 30
Slide 30 text
h関数のTypeScript版 https://github.com/syumai/minimum-jsx/blob/main/basic/src/jsxRenderer.ts © LayerX Inc. JSX namespaceの IntrinsicElements には、組み込み要素 (小文字始まり) の名前、プロ パティの組を指定する 今回は、どんな名前の要素も通す設定にしている これが無いと、 Hello! などの式が型エラーになってしまう 30
Slide 31
Slide 31 text
tsconfigへの設定の追加 https://github.com/syumai/minimum-jsx/blob/main/tsconfig.base.json © LayerX Inc. JSXのトランスパイル設定に react 、Factory関数に h を使用することを指定 31
Slide 32
Slide 32 text
実行結果 これも動いた!🎉 © LayerX Inc. 32
Slide 33
Slide 33 text
組み込み要素を実装する
Slide 34
Slide 34 text
組み込み要素を実装する 組み込み要素として、以下を実装 © LayerX Inc. 条件を満たした時だけchildrenを返す if 要素 34
Slide 35
Slide 35 text
例: 以下を結果に期待 https://github.com/syumai/minimum-jsx/blob/main/control-flow/src/index.tsx © LayerX Inc. 35
Slide 36
Slide 36 text
if要素の実装 https://github.com/syumai/minimum-jsx/blob/main/control-flow/src/jsxRenderer.ts © LayerX Inc. 条件を満たすかどうかで children か null を分岐 36
Slide 37
Slide 37 text
h関数の実装 © LayerX Inc. type の文字列を見て、 "if" だったら ifElem の処理を呼ぶ 37
Slide 38
Slide 38 text
実行結果 動いた!🎉 © LayerX Inc. 38
Slide 39
Slide 39 text
コンポーネントを使えるようにする
Slide 40
Slide 40 text
ここでの「コンポーネント」とは © LayerX Inc. JSXの要素名に指定して使い回せる関数のことをコンポーネントと呼びます 40
Slide 41
Slide 41 text
TypeScriptのドキュメント上の要素 (element) の分類 https://www.typescriptlang.org/docs/handbook/jsx.html © LayerX Inc. TypeScriptのドキュメントでは、以下のように要素の種類を分類している intrinsic elements 組み込み要素 名前が小文字で始まる value-based elements JSXの式の書かれたスコープ内で参照可能な識別子で指定 名前が大文字で始まる 今回コンポーネントと呼んでいるのはこちら 41
Slide 42
Slide 42 text
コンポーネントを使えるようにする https://github.com/syumai/minimum-jsx/blob/main/components/src/index.tsx © LayerX Inc. 今回使えるようにしたいのは以下の2コンポーネント Messages: childrenを , で結合した文字列を返す Message: text プロパティの文字列を返す 42
Slide 43
Slide 43 text
h関数の実装 https://github.com/syumai/minimum-jsx/blob/main/components/src/jsxRenderer.ts © LayerX Inc. type が関数の場合、呼び出した結果を返す 文字列なら従来通りの動作 43
Slide 44
Slide 44 text
JSX namespaceの修正 https://github.com/syumai/minimum-jsx/blob/main/components/src/jsxRenderer.ts © LayerX Inc. Messages が子要素を受け取れるようにするために、 ElementChildrenAttribute を追加 44
Slide 45
Slide 45 text
実行してみる https://github.com/syumai/minimum-jsx/blob/main/components/src/index.tsx © LayerX Inc. 45
Slide 46
Slide 46 text
実行結果 動いた!🎉 © LayerX Inc. 46
Slide 47
Slide 47 text
コンポーネントの戻り値の型について
Slide 48
Slide 48 text
コンポーネントの戻り値の型について © LayerX Inc. h関数からはどんな値を返してもOKだった つまり、JSXの式は、どんな値を返してもいい ということは、コンポーネントの戻り値の型は任意の型にできるか…? 48
Slide 49
Slide 49 text
→ できない!
Slide 50
Slide 50 text
JSXの要素の型の制約 © LayerX Inc. JSXの要素 (JSXの式を評価した結果) の型は、 JSX.Element 型の1種類になる 50
Slide 51
Slide 51 text
JSXの要素の型の制約 © LayerX Inc. stringとnumberを返すコンポーネントをそれぞれ定義しても、式の評価結果は両方とも JSX.Element 型になってしまう 51
Slide 52
Slide 52 text
JSXの要素の型の制約 © LayerX Inc. string | number などと指定しても、使うコンポーネントの種類で型が決まらない JSXの式の評価結果が string の1種類に定まるようなケースではある程度有効かもしれ ない? しかし、ユーザー定義のコンポーネントがどう書かれるか制約できないので厳しい 52
Slide 53
Slide 53 text
https://www.typescriptlang.org/docs/handbook/jsx.html © LayerX Inc. 53
Slide 54
Slide 54 text
まとめ © LayerX Inc. JSXは、HTMLに囚われない多様なユースケースに使える JSXランタイムの実装は小さく始めたら簡単 JSXの要素の型には制約があり、表現力の限界がある 54
Slide 55
Slide 55 text
今回のサンプルリポジトリ https://github.com/syumai/minimum-jsx © LayerX Inc. 55
Slide 56
Slide 56 text
おすすめ資料 © LayerX Inc. uhyoさんの「自前のJSX実装を作るために必要な全ての知識」 全てがここにあるので、ちゃんとしたJSXランタイムを作りたくなったらこれを読んでください Mahitoさんの「childrenの順序まで型で縛る ── Branded Typesで実践するJSXの構造 安全」 JSXの型の表現力の限界に独自のアプローチで取り組んだ発表の資料です 56