Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
SvelteのHTMLはどう解釈されているのか / How Svelte compile HTML
Search
yamanoku
July 17, 2026
130
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
SvelteのHTMLはどう解釈されているのか / How Svelte compile HTML
Svelte Japan Offline Meetup #8
発表資料
yamanoku
July 17, 2026
More Decks by yamanoku
See All by yamanoku
Navigation APIと見るSvelteKitのWeb標準志向
yamanoku
2
210
Shifting from MCP to Skills / ベストプラクティスの変遷を辿る
yamanoku
5
1.1k
SchooでVue.js/Nuxtを技術選定している理由
yamanoku
4
8.8k
たかがボタン、されどボタン ~button要素から深ぼるボタンUIの定義について~ / BuriKaigi 2026
yamanoku
1
520
ひとりNavigation API Advent Calendarの紹介 / Mita.ts #9
yamanoku
1
200
DenoとJSRで実現する最速MCPサーバー開発記 / Building MCP Servers at Lightning Speed with Deno and JSR
yamanoku
2
690
転生したらTypeScriptのEnumだった件 ~型安全性とエコシステムの変化で挫けそうになっているんだが~ / TSKaigi 2025
yamanoku
0
79
React 18からのAPI useIDを使おう!/ Let's Use the useID API from React 18
yamanoku
0
190
リアクティブシステムの変遷から理解するalien-signals / Learning alien-signals from the evolution of reactive systems
yamanoku
3
2.1k
Featured
See All Featured
The Language of Interfaces
destraynor
162
27k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
890
WENDY [Excerpt]
tessaabrams
11
38k
Designing for humans not robots
tammielis
254
26k
Git: the NoSQL Database
bkeepers
PRO
432
67k
Docker and Python
trallard
47
3.9k
We Have a Design System, Now What?
morganepeng
55
8.2k
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.6k
Marketing to machines
jonoalderson
1
5.6k
Building Adaptive Systems
keathley
44
3.1k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
201
75k
Site-Speed That Sticks
csswizardry
13
1.3k
Transcript
Svelte の HTML は どう解釈されているのか Svelte Japan Offline Meetup #8
2026/07/17 yamanoku
やまのく yamanoku 一児の父・会社員 「お元気ですか.fm」パーソナリティ • Web Standard • フロントエンド •
UIデザイン • アクセシビリティ • 大型犬 X (旧Twitter) | BlueSky | GitHub
最近 HTML を 気にしている
AIがドキュメントを 生成してくれる時代
Markdownだと 表現力が乏しい
多彩な表現をするなら HTMLがいいよね
書かせるなら正しい HTMLにしたいよね
我々がよく目にする HTML
UIライブラリでの HTML
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>
Astro の HTML(.astro) --- import HomeLayout from '../layouts/HomeLayout.astro'; --- <HomeLayout>
<title slot="head">Astro</title> <h1>Astro</h1> </HomeLayout>
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> </>; }
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>
本題 Svelte の HTML は どう解釈されているのか
Parse, Analyze, Transformの順に実行する 1. Parse: .svelte ファイルを解析し、AST.Rootを生成 2. Analyze: ASTの解析、統計・警告
3. Transform: ASTをJavaScriptコードとして変換 Svelte コンパイラのフェーズ
Root — ファイル全体(簡略版) ├ instance(ルート直下の <script>) ├ css(ルート直下の <style>) └
Fragment Text / Comment / Component RegularElement └ これが HTML 要素である判定 1. ParseにてASTを作成
1. ParseにてASTを作成 // 字句解析と構文解析を分けず、 // 現在位置 (index) を進めながらASTを直接組み立てるスタイル /** @type
{ParserState} */ let state = fragment; while (this.index < this.template.length) { state = state(this) || fragment; }
{ }という記号がいくつもの用途で使われ詳細な字句解析ができない • HTMLの途中にある場合 例:<h1>Hello {name}</h1> • <script> タグの中にある場合 例:if
(x) { ... } • <style> タグの中にある場合 例:h1 { color: red; } 今どこを読んでいるか(文脈)を重視してパースを行っている Q. なぜ字句解析と構文解析を分けないのか?
要素として何が含まれているかをASTの内容を解析する その後、属性名の不正文字チェック、ディレクティブ検証や アクセシビリティチェックといった Compiler warnings の内容を扱う • validate_element(node, context); •
check_element(node, context); 2. AnalyzeにてASTの内容を解析
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特有の情報) }
1. 受け取った AST の情報を JavaScript コードとして変換 2. 内容が動的なもの(リアクティブな値があるか等)かどうか判別 3. HTML
文字列をDOMノードへ変換し、DOM ツリーへ挿入される 4. ユーザーが mount()するときに呼び出してdocument.bodyとして 挿入される 3. TransformにてJavaScriptコードに置換
3. TransformにてJavaScriptコードに置換 // 静的なコード判定の場合: // テンプレートとして静的 HTML を生成 var img
= $.template(`<img src="avatar.png">`); export function MyComponent($$anchor) { var node = $.first_child(img()); $.append($$anchor, node); }
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); }
本家 sveltejs/svelte の設計を参考に、HTML 解析だけを対象にした 小さなコンパイラをAIエージェント一緒に作成してみた。 https://github.com/yamanoku/svelte-mini-compiler 理解のため小さい Svelte コンパイラを作った
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に変換
• mustache構文( { } / {#if} )は非対応。HTML のみ • <script>
内は .svelte ファイルの import のみ許可 • analyze にスコープ解決・リアクティビティ解析はない • コンポーネントは「呼び出し」のみ。props、slot は非対応 • 相互 import(A → B → A)は実行時に無限再帰する • <style> はスコープ処理はしない 簡略化した部分
デモ 実際に内容を見てみよう
• 簡易的だが仕組みを知れるきっかけになれた ◦ どういう順序でコンパイルするのかの仕組み ◦ ASTの構成内容 ◦ warningsはどのように追加されるのか ▪ a11y_warnings関連のコントリビュートきっかけにしたい
• Vue.js や他UIライブラリでのコンパイルも気になる ◦ 簡易的なものとしての chibivue という学習コンテンツ 所感:svelte-mini-compilerを作ってみて
• HTML は Living Standard である • 知識自体は随時アップデートしていかないといけない • 使える要素はどのタイミングで入れるのだろうか
• Baseline の情報も含めると良いのだろうか ◦ ちなみに Svelte は Baseline 2020 相当とのこと • 参照する一次情報として WebIDL、Elements のパッケージがあるので それを使った検知ができる 私見:HTML の知識をもつコンパイラについて
• Svelte のCompiler Warning ◦ svelte-check ◦ rsvelte by baseballyama
• ESLint ◦ eslint-plugin-svelte, html-eslint • Markuplint by Yusuke Hirao • Nu Html Checker ◦ ページ全体をチェックする 疑問:Svelte の HTML は誰が守る?
None
• ubugeeei氏による Vue.js のRustツールチェイン集 • Compile、Type Check、Format、Lint など • Alt
Storybookとしてのコンポーネントギャラリー機能 • LSPによるエディタサポート 私の Nuxt のサイトを Vize と独自レンダラー構成にされました 詳細:とあるサイトがkingnizeされるまで~Nuxtからvuerend & Vizeへ Vizeとは何か
feat(patina): port uncovered rules from eslint-plugin-{react,vue,svelte,vuejs-a11y} · Issue #1629 ·
ubugeeei-prod/vize
UIライブラリ、コンパイラ、 Lint… 色んな方法で HTMLを見直していこう
宣伝
8月8日は何の日?
None
HTML Night in Tokyo ~HTML DAY 2026 PRE EVENT~ •
8/7(金)開催 • 会場提供:アララ株式会社 様 HTML Day 2026 in 東葛 • 8/8(土)開催 • 会場:スターツおおたかの森ホール • その他、東京・京都・北海道でHTML Dayが開催予定 HTMLにまつわるイベントやります
• sveltejs/svelte • chibivue • DeepWiki • Claude Fable 5
• Gemini 3.5 謝辞