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
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
540
ひとり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
83
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
Large-scale JavaScript Application Architecture
addyosmani
515
110k
The Invisible Side of Design
smashingmag
301
52k
Building Flexible Design Systems
yeseniaperezcruz
330
40k
How GitHub (no longer) Works
holman
316
150k
Marketing to machines
jonoalderson
1
5.6k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
340
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
260
Chasing Engaging Ingredients in Design
codingconduct
0
260
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.2k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
270
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
350
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
480
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 謝辞