Share
Embed
Transcript
54 slides
-
Vue Fes 2025 から Astro Japan Community へ pilcrow @pilcrowonpaper
Why isn’t anyone from @astrodotbuild here at @vuefes :( Astro @astrodotbuild @jp_knj was there! pilcrow @pilcrowonpaper We need more people! Astro @astrodotbuild Who is organizing Astro meetups in Japan? -
話すこと 1. 当時の判断 なぜ最初に Go を選んだのか 2. 発見した問題 使い続けるなかで何が見えたのか 3.
前提の変化 2026年までに周囲はどう変わったのか 4. 新しい判断 その結果、責務をどう分け直したのか -
Astro 0.x の出発点 .astro Svelte Compiler fork を拡張 Astro の構文を変換し、ビルド基盤へ渡す
VITE: The Documentary(Snowpack の話は 7:40 から) Snowpack ビルドと配信 Browser -
2021 年、Go と Rust が選ばれていた Feb Sep Oct Oct Nov
Dec Vite 2.0 Rome Parcel 2 Next.js 12 Astro 0.21 Turborepo esbuild を利用 -
Astro v1 の構成 2022 年 ビルドのためのコンパイラだった。 Go Compiler .astro HTML5
Parser esbuild(CSS) Nate Moore が挙げた Go の選定理由 esbuild が Go だった。Go は学びやすかった。 Nate Moore: Hello from the other side VITE: The Documentary(Astro の Vite 採用は 20:21 から) Vite Rollup esbuild Browser -
Astro Template Syntax --const products = await getProducts(); --Component script
--- で囲む。ビルド時とサーバーで実行する JavaScript と TypeScript Astro Template Syntax -
Astro Template Syntax --const products = await getProducts(); --<ul> <!--
template --> </ul> Template HTML を基礎に、コンポーネントを書ける。 Astro Template Syntax -
Astro Template Syntax --const products = await getProducts(); --<ul> {products.map((product)
=> ( <li>{product.name}: {product.price}</li> ))} </ul> JavaScript expression Astro の書き方って、JSX っぽい Astro Template Syntax -
Astro Template Syntax --const products = await getProducts(); const props
= { title: "second" }; --<ul> {products.map((product) => ( <li title="first" { ... props}>{product.name}</li> ))} </ul> Q. この title は、どちらの値になる? first か、 second か -
Astro Template Syntax --const products = await getProducts(); const props
= { title: "second" }; --<ul> {products.map((product) => ( <li title="first" { ... props}>{product.name}</li> ))} </ul> A. first astro#5558 の説明 -
Astro Template Syntax --const products = await getProducts(); constの規則で扱ったため props
= { title: "second" }; HTML --同じタグに同じ名前の属性が複数あると、ブラウザは先に書かれた属性の値を使う。 <ul> {products.map((product) => ( HTML Standard の重複属性の扱い <li title="first" { ... props}>{product.name}</li> ))} </ul> -
Astro Template Syntax ブラウザが空白にする <span>Hello</span> <span>World</span> 要素間の改行を HTML に保持した。 ブラウザがその改行を空白として表示し、
Hello World になった。 astro#6011: 要素間の空白テキスト node HTML Whitespace is Broken -
Astro Template Syntax .astro 生成された HTML <table> <tr><td>{'foo'}</td></tr> </table> <h2>Chats</h2>
<table> <tr><td>foo</td></tr> <h2>Chats</h2> </table> -
Astro Template Syntax HTML .astro の規則による補正 生成された HTML Go Compiler
<table> は HTML5 Parser を拡張し、 <table> <tr><td>{'foo'}</td></tr> <tr><td>foo</td></tr> ビルド時にもタグの補完と入れ子の補正を担っていた。 </table> 表のパースの不具合報告 <h2>Chats</h2> HTML Standard のパース規則 <h2>Chats</h2> </table> -
Astro v2〜v5 2023〜2025年 ビルドに加え、書いている間のサポートも必要になる Editor Linter と Formatter と Language
Tool Go Compiler .astro HTML5 Parser esbuild(CSS) Vite esbuild Browser -
Linter が検査を始めるまで Go Compiler が返す Astro AST { } ※1
type: "expression", children: [{ type: "text", value: "price * amount" }] TextNode.value ※2 .astro の構文は Espree ※3 へ直接渡せない --const price = 10; const amount = 3; --<p>{price * amount}</p> は文字列 JavaScript expression の識別子と演算子が必要 ※1 AST は、コードの文法上のまとまりを木で表したデータ。 ※2 TextNode は、文字列を値として持つ node。 ※3 Espree は、JavaScript と JSX をパースして AST を返すライブラリ。 -
Linter が検査を始めるまで JavaScript と JSX const price = 10; const
amount = 3; <> <p>{price * amount}</p> </>; .astro を JavaScript と JSX に変換する Espree ※3 JavaScript expression の AST BinaryExpression ├─ operator: "*" ├─ left: Identifier │ └─ name: "price" └─ right: Identifier └─ name: "amount" BinaryExpression は二項演算 Identifier は識別子 でパースし、変数名と演算子を AST の項目として取得する ※1 AST は、コードの文法上のまとまりを木で表したデータ。 ※2 TextNode は、文字列を値として持つ node。 ※3 Espree は、JavaScript と JSX をパースして AST を返すライブラリ。 ※1 -
位置の対応と位置情報の不具合 変換後の JavaScript と JSX .astro <><p>{price * amount}</p> <p>{price
* amount}</p> [46, 51) [49, 54) Go Compiler position: { start: { offset: 47 }, end: { offset: 80 } } 波かっこの範囲と一致しない 波かっこを含む正しい範囲 position: { start: { offset: 48 }, end: { offset: 64 } } {price * amount} -
Formatter が整形を始めるまで .astro {true ? <p>OK</p> : null} Go Compiler
が返す Astro AST expression ├─ TextNode.value "true ? " ├─ p │ └─ TextNode.value "OK" └─ TextNode.value " : null" JavaScript expression 全体の AST はない -
Formatter が整形を始めるまで Astro plugin で連結中のコード "true ? " + "<p>OK</p>"
+ " : null" TextNode.value をそのまま使う p 要素を文字列に戻す TextNode.value をそのまま使う 文字列を組み立てる工程でも、エッジケースへの対応が必要 連結結果 true ? <p>OK</p> : null Babel に渡す前 <>{true ? <p>OK</p> : null}</> expression の AST を得るため、JSX で囲んで再パースする -
Go Compiler と Language Tool の分担 .astro Go Compiler TSX
※ Source map Language Tool Go Compiler では、JavaScript の構文の判別を独自の Scanner で実装していました。 書きかけの JavaScript にも対応しながら、TSX を生成する必要があった。 ※ Source map は、変換前後のコードの位置対応を記録したデータ。 Go Compiler と Language Tool の連携 TSX 生成を見直した背景 -
Compiler はどうあるべきか Compiler に求めること Astro のタグに加えて、JavaScript expression の AST も返す
正確な位置情報を返し、TSX への変換でも型の情報と位置の対応を保つ 開発チームが修正を続けられる実装にする 新 Compiler と Prettier plugin の検討 Compiler の保守範囲を見直す公開提案 -
Rust とフロントエンドツールチェーン SWC Oxc Biome Lightning CSS JavaScript と TypeScript
の Compiler Parser と Compiler Linter と Formatter 検査と整形と LSP CSS の変換と最適化 Rolldown Rspack Turbopack Turborepo バンドル バンドル Next.js のバンドル タスク実行 -
Oxc を Parser として利用する .astro <p>{price * amount}</p> Oxc Parser
expression を Oxc へ import { parseSync } from "oxc-parser"; const { program } = parseSync( "example.js", "price * amount", ); Oxc Parser AST 識別子と演算子 -
Lossless CST のよさ ※1 price * amount; // 税込 Prettier
と Babel // AST { type: "BinaryExpression", operator: "*", left: { name: "price" }, right: { name: "amount" } } // コメント [{ type: "CommentLine", value: " 税込" }] Biome の Lossless CST // CST の模式図 ExpressionStatement ├─ BinaryExpression │ ├─ "price" [空白 2] │ ├─ "*" [空白 1] │ └─ "amount" └─ ";" [空白 1 と "// 税込"] ※1 Lossless CST は、空白とコメントと改行も保持する構文の木。 ※2 rowan は rust-analyzer でも使われる構文木ライブラリ。Biome は fork して利用。 ※2 -
Biome の Lossless CST で書式を保つ この 1 か所の price を
unitPrice に変えたい 変更前 price * amount; // 税込 CST の名前の部分だけを変更 変更後 unitPrice * amount; // 税込 空白 2 文字とコメントと末尾の改行は、そのまま 変更しない部分の書式を保ったまま、修正できる ※ rust-analyzer でも使われている rowan を基に実装 Biome の Parser と CST -
TypeScript との連携 TypeScript は Go へ .astro .vue .svelte Content
Mapper .mdx TypeScript のネイティブ移行 Astro の Content Mapper の実装 Content Mapper の仕様と実装 TypeScript 7.1 -
Astro が実装して保守する範囲 .astro <style> Compiler の実装と依存関係 AST Astro の Oxc
Parser Astro Codegen JavaScript Lightning CSS Astro の CSS スコープ CSS -
Astro Template Syntax の振る舞い 書かれた親子関係を保つ .astro 生成された HTML <table> <tr><td>{'foo'}</td></tr>
</table> <h2>Chats</h2> <table> <tr><td>foo</td></tr> </table> <h2>Chats</h2> Compiler は HTML 補正を行わない。 HTML 補正を行わない方針 Astro Template Syntax の仕様ドラフト -
Astro Template Syntax の振る舞い 空白を JSX の規則で扱う .astro <span>Hello</span> <span>World</span>
Astro v7 は標準で compressHTML: 'jsx' Astro v7 の空白規則 Astro Template Syntax の仕様ドラフト ブラウザでの表示 HelloWorld -
Oxfmt と Astro Oxfmt Biome Formatter Oxfmt の Astro 対応計画
Biome Formatter の再利用 Astro plugin の実装 Prettier plugin Rust Compiler -
TSX と位置対応 @astrojs/astro2tsx .astro Astro Language Tool TypeScript Language Tool
と Volar の連携 Content Mapper が返すデータ Editor TSX と位置対応 Content Mapper @astrojs/ts-content-mapper TypeScript 7.1 -
MDX の試作とライブラリへの貢献 2025 年 7 月 2025 年 8 月
Astro への統合を提案 🦀 Rust Compiler MDX を速くしたい 🤝 🚀 Astro AST Bridge 🌳 2025 年 8 月 ※1 を提案 🧩 JavaScript plugin Rust の AST remark と rehype も使いたい ※2 markdown-rs に提案 🌳 🧩 🌳 AST plugin AST Rust の中で AST を変更 JavaScript との往復を減らす 試作をきっかけに、交流がはじまった。 ※1 AST Bridge は、Rust でパースした AST を JavaScript のプラグインへ渡す提案。 ※2 remark は Markdown、rehype は HTML の変換をプラグインで拡張する仕組み。 -
Processor を自作して Astro に組み込む Starlight のサイトが利用 Astro 利用 導入 Astro
integration Vite hook を実行 登録 Vite plugin Astro の モジュールに変換 呼び出し Node-API bindings ※ 呼び出し JavaScript から Rust を呼ぶ ※ Node-API bindings は、Node.js とネイティブコードの間で関数と値を受け渡す部分。 xmdx と Astro integration Compiler Rust でパースと変換 MDX のコードを生成 -
Processor を自作して Astro に組み込む Starlight のサイトが利用 Astro 利用 導入 Astro
integration Vite hook を実行 登録 Vite plugin Astro の モジュールに変換 呼び出し Node-API bindings ※ 呼び出し JavaScript から Rust を呼ぶ ※ Node-API bindings は、Node.js とネイティブコードの間で関数と値を受け渡す部分。 xmdx と Astro integration Compiler Rust でパースと変換 MDX のコードを生成 -
Sätteri とは ドイツの Seibert で Louis Escher が紹介 Astro Together
FRA × Seibert(11:40 から) Erika の Sätteri 紹介 Sätteri のドキュメント Astro 公式のイベント案内 -
最初の問いへの答え 当時の判断 発見した問題 Go は学びやすい expression の AST を取得できない HTML5
Parser の拡張 位置の対応と位置情報の修正 esbuild の CSS Parser の利用 HTML 補正と TSX 生成の保守 前提の変化 新しい判断 Oxc と Lightning CSS Astro が実装して保守する範囲を絞る Biome の Lossless CST AST と位置情報をツールへ返す TypeScript と Content Mapper Astro Template Syntax の規則を共有 -
ロゴのクレジット Go Gopher Biome Renee French 配布元 と CC BY
4.0 背景を除去し、透過画像に編集 Alexandru-Ștefan Gârleanu Biome Core Contributors and Maintainers 配布元 と CC BY-SA 4.0 Oxc Vue Oxc project 配布元 と CC BY-NC-SA 4.0 Evan You 配布元と追加条件 CC BY-NC-SA 4.0 HTML5 W3C 配布元 と CC BY 3.0 Biome と Oxc と Vue と HTML5 は Iconify の SVG も利用(SVG の最適化あり)