Upgrade to Pro — share decks privately, control downloads, hide ads and more …

SvelteのHTMLはどう解釈されているのか / How Svelte compile HTML

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for yamanoku yamanoku
July 17, 2026
4

SvelteのHTMLはどう解釈されているのか / How Svelte compile HTML

Avatar for yamanoku

yamanoku

July 17, 2026

More Decks by yamanoku

Transcript

  1. Vue.js の HTML(.vue) <script setup> import { ref } from

    'vue'; const msg = ref('Hello World!'); </script> <template> <h1>{{ msg }}</h1> <input type=”text” v-model="msg" /> </template>
  2. Ripple TS の HTML(.tsrx) import { track } from 'ripple';

    export default function Counter() { let &[count] = track(0); let &[double] = track(() => count * 2); return <> <div class="container"> <h2>"Counter"</h2> <p>"Count: "{count}</p> <button type=”button” onClick={() => count--}>"-"</button> <button type=”button” onClick={() => count++}>"+"</button> </div> </>; }
  3. Svelte の HTML(.svelte) <script> let name = $state('world'); let count

    = $state(0); </script> <h1>Hello {name}!</h1> <input type=”text” bind:value={name} /> <button type=”button” onclick={() => count += 1}> clicks: {count} </button>
  4. Root — ファイル全体(簡略版) ├ instance(ルート直下の <script>) ├ css(ルート直下の <style>) └

    Fragment Text / Comment / Component RegularElement └ これが HTML 要素である判定 1. ParseにてASTを作成
  5. 1. ParseにてASTを作成 // 字句解析と構文解析を分けず、 // 現在位置 (index) を進めながらASTを直接組み立てるスタイル /** @type

    {ParserState} */ let state = fragment; while (this.index < this.template.length) { state = state(this) || fragment; }
  6. { }という記号がいくつもの用途で使われ詳細な字句解析ができない • HTMLの途中にある場合 例:<h1>Hello {name}</h1> • <script> タグの中にある場合 例:if

    (x) { ... } • <style> タグの中にある場合 例:h1 { color: red; } 今どこを読んでいるか(文脈)を重視してパースを行っている Q. なぜ字句解析と構文解析を分けないのか?
  7. 2. AnalyzeにてASTの内容を解析 // <img src=”avatar.png”> を解析する { type: 'RegularElement', //

    ASTノードの種類 name: 'img', // HTML要素 start: ..., // 文字オフセット始点(バイトデータ) end: ..., // 文字オフセット終点(バイトデータ) name_loc: { ... }, // SourceLocation情報 attributes: [ { ... } ], // 要素の属性値(src=”avatar.png”部分) fragment: { ... }, // 要素の子ノード情報 metadata: { ... } // メタデータ(RegularElement特有の情報) }
  8. 1. 受け取った AST の情報を JavaScript コードとして変換 2. 内容が動的なもの(リアクティブな値があるか等)かどうか判別 3. HTML

    文字列をDOMノードへ変換し、DOM ツリーへ挿入される 4. ユーザーが mount()するときに呼び出してdocument.bodyとして 挿入される 3. TransformにてJavaScriptコードに置換
  9. 3. TransformにてJavaScriptコードに置換 // 静的なコード判定の場合: // テンプレートとして静的 HTML を生成 var img

    = $.template(`<img src="avatar.png">`); export function MyComponent($$anchor) { var node = $.first_child(img()); $.append($$anchor, node); }
  10. 3. TransformにてJavaScriptコードに置換 // 動的なコード(リアクティブな値)判定の場合: // テンプレートには src なし var root

    = $.template(`<img>`); export default function MyComponent($$anchor, $$props) { let url = $.state('avatar.png'); var img = root(); $.template_effect(() => $.set_attribute(img, 'src', $.get(url))); $.append($$anchor, img); }
  11. svelte-mini-compilerと本家の対応比較 svelte-mini-compiler packages/svelte/src/compiler 役割 index.ts index.js の compile() 3フェーズを順に実行するエントリポイント phases/1-parse/

    phases/1-parse/ の Parser 手書き再帰下降パーサ本体 phases/2-analyze/ phases/2-analyze/ AST の walk と警告収集・import 解決 phases/3-transform/ phases/3-transform/client/ AST から JavaScript コード文字列を生成 build.ts Vite + vite-plugin-svelte import グラフをたどり各 .svelte をJSに変換
  12. • mustache構文( { } / {#if} )は非対応。HTML のみ • <script>

    内は .svelte ファイルの import のみ許可 • analyze にスコープ解決・リアクティビティ解析はない • コンポーネントは「呼び出し」のみ。props、slot は非対応 • 相互 import(A → B → A)は実行時に無限再帰する • <style> はスコープ処理はしない 簡略化した部分
  13. • 簡易的だが仕組みを知れるきっかけになれた ◦ どういう順序でコンパイルするのかの仕組み ◦ ASTの構成内容 ◦ warningsはどのように追加されるのか ▪ a11y_warnings関連のコントリビュートきっかけにしたい

    • Vue.js や他UIライブラリでのコンパイルも気になる ◦ 簡易的なものとしての chibivue という学習コンテンツ 所感:svelte-mini-compilerを作ってみて
  14. • HTML は Living Standard である • 知識自体は随時アップデートしていかないといけない • 使える要素はどのタイミングで入れるのだろうか

    • Baselineの 情報も含めると良いのだろうか ◦ ちなみに Svelte は Baseline 2020 相当とのこと • 参照する一次情報として WebIDL、Elements のパッケージがあるので それを使った検知ができる 私見:HTML の知識をもつコンパイラについて
  15. • Svelte のCompiler Warning ◦ svelte-check ◦ rsvelte by baseballyama

    • ESLint ◦ eslint-plugin-svelte, html-eslint • Markuplint by Yusuke Hirao • Nu Html Checker ◦ ページ全体をチェックする 疑問:Svelte の HTML は誰が守る?
  16. • ubugeeei氏による Vue.js のRustツールチェイン集 • Compile、Type Check、Format、Lint など • Alt

    Storybookとしてのコンポーネントギャラリー機能 • LSPによるエディタサポート 私の Nuxt のサイトをと Vize と独自レンダラー構成にされました 詳細:とあるサイトがkingnizeされるまで~Nuxtからvuerend & Vizeへ Vizeとは何か
  17. HTML Night in Tokyo ~HTML DAY 2026 PRE EVENT~ •

    8/7(金)開催 • 会場提供:アララ株式会社 様 HTML Day 2026 in 東葛 • 8/8(土)開催 • 会場:スターツおおたかの森ホール • その他、東京・京都・北海道でHTML Dayが開催予定 HTMLにまつわるイベントやります