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