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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
yamanoku
July 17, 2026
240
1
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
220
Shifting from MCP to Skills / ベストプラクティスの変遷を辿る
yamanoku
5
1.1k
SchooでVue.js/Nuxtを技術選定している理由
yamanoku
4
8.8k
たかがボタン、されどボタン ~button要素から深ぼるボタンUIの定義について~ / BuriKaigi 2026
yamanoku
1
530
ひとりNavigation API Advent Calendarの紹介 / Mita.ts #9
yamanoku
1
210
DenoとJSRで実現する最速MCPサーバー開発記 / Building MCP Servers at Lightning Speed with Deno and JSR
yamanoku
2
700
転生したらTypeScriptのEnumだった件 ~型安全性とエコシステムの変化で挫けそうになっているんだが~ / TSKaigi 2025
yamanoku
0
82
React 18からのAPI useIDを使おう!/ Let's Use the useID API from React 18
yamanoku
0
200
リアクティブシステムの変遷から理解するalien-signals / Learning alien-signals from the evolution of reactive systems
yamanoku
3
2.1k
Featured
See All Featured
Build your cross-platform service in a week with App Engine
jlugia
234
19k
A Modern Web Designer's Workflow
chriscoyier
698
190k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
201
75k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
330
Ethics towards AI in product and experience design
skipperchong
2
340
Reality Check: Gamification 10 Years Later
codingconduct
0
2.2k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
1.7k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Amusing Abliteration
ianozsvald
1
240
A better future with KSS
kneath
240
18k
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
190
Rails Girls Zürich Keynote
gr2m
96
14k
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; }
1. ParseにてASTを作成 /** @param {Parser} parser */ export default function
fragment(parser) { if (parser.match('<')) { return element; // HTML、SVG、Svelteコンポーネントの要素 } if (parser.match('{')) { return tag; // {#if}や{#each}などのSvelteの式タグ } return text; // テキスト部分 }
Svelte REPL の「AST output」を確認してみよう! どのように ASTに変換されるかを見る
要素として何が含まれているかを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 謝辞