$30 off During Our Annual Pro Sale. View Details »

TSX First な Zero-Runtime SSG potato4d/dodai とその仕組み / owned static site generator #kyotojs

TSX First な Zero-Runtime SSG potato4d/dodai とその仕組み / owned static site generator #kyotojs

2023/02/03 に開催された、 #kyotojs での発表時の登壇資料です。

Potato4d(Hanatani Takuma)

February 03, 2023
Tweet

More Decks by Potato4d(Hanatani Takuma)

Other Decks in Programming

Transcript

  1. 2023/02/03 #kyotojs Takuma HANATANI(@potato4d)
    TSX First な Zero-Runtime SSG
    @potato4d/dodai とその仕組み

    View Slide

  2. - ⾃⼰紹介
    - @potato4d/dodai の概要
    - 既存ソリューションの課題感とアンサー
    - ビルドの仕組み
    - おわりに
    ■ Agenda

    View Slide

  3. - ⾃⼰紹介
    - @potato4d/dodai の概要
    - 既存ソリューションの課題感とアンサー
    - ビルドの仕組み
    - おわりに
    ■ Agenda

    View Slide

  4. @potato4d
    - LINE株式会社のエンジニアリングマネージャー
    - 副業で合同会社ElevenBackの代表
    - 普段は HR 領域のプロダクトの開発・マネジメント
    - プロダクトのスタックは React/TypeScript が中⼼
    - React & Styled & React Query と Next.js & Chakra +α
    - 関⻄出⾝で今⽇は東京から戻ってきました 🏃💨

    View Slide

  5. - ⾃⼰紹介
    - @potato4d/dodai の概要
    - 既存ソリューションの課題感とアンサー
    - ビルドの仕組み
    - おわりに
    ■ Agenda

    View Slide

  6. @potato4d/dodai
    ランタイムJSゼロ 最⼩限の洗練された機能
    All TSX で構築可能
    https://github.com/potato4d/dodai
    テンプレート記述はすべてTSXであり
    専⽤のテンプレートエンジンは不要。
    SPA開発と同じ技術でサイトも構築
    全ての処理をビルドタイムで実⾏。
    ランタイムJSにはオピニオンを持たな
    いため軽快であり、かつ機能拡張時は
    任意の技術でハイドレーション可能。
    パスベースのルーティング、ホットリ
    ロードなど欲しい機能は完備。静的
    サイト出⼒以外の機能は持たず、アッ
    プデートのコストは最⼩限。
    想定ケースは1~5個の固定ページと
    N個の動的ページがあるサイト

    View Slide

  7. - ⾃⼰紹介
    - @potato4d/dodai の概要
    - 既存ソリューションの課題感とアンサー
    - ビルドの仕組み
    - おわりに
    ■ Agenda

    View Slide

  8. 既存のSSGソリューションの課題点
    - アプリケーションエンジニア寄りの技術は Too much になりすぎる
    - Next/Nuxt などはリッチすぎてアップデート追従のコストが⾼い
    - Astro などは DSL が⼀級市⺠であり、TSX 対応はあれど最優先ではない
    - Webサイト制作寄りの技術は SPA 技術との格差がありすぎる
    - Numjucks など機能⾯で下位互換のDSLは恩恵が薄い
    - データの取扱を型など含めて安全に取り回せる技術がない

    View Slide

  9. ワガママなWeb Appエンジニアが実現したいこと
    できればSPA開発と同じ
    TypeScriptに守られたTSXで
    HTML・データを管理したい
    更新頻度が低いWebサイトの
    依存関係に悩まされたくない
    技術スタックはそのままに
    ランタイムで動くJSはゼロにしたい

    View Slide

  10. 技術……
    • Web App エンジニア向けの技術で
    • SSR/ISRをしないような更新頻度と規模のサイトを
    • 低い開発コストかつ高いDXのもと開発する

    View Slide

  11. 技術……
    • Web App エンジニア向けの技術で
    • SSR/ISRをしないような更新頻度と規模のサイトを
    • 低い開発コストかつ高いDXのもと開発する
    結論:ニーズが狭いので自分で見繕うしかない

    View Slide

  12. 作った

    View Slide

  13. dodai での解決 ①
    TSX First
    - Reactを利⽤しており、いつもの記法でコーディング
    - export const でページのレンダリングを表現
    Everything is TypeScript
    - 動的ページの出⼒データも export const で管理
    - 安全にページデータの取扱が可能

    View Slide

  14. pages/items/[item].tsx の例。
    Head が 内に、 Page が layouts/default.tsx の children にて描画される。

    View Slide

  15. layouts/default.tsx のデフォルトの設定。
    head と children を受け取り、それぞれ適切に描画を行う。

    View Slide

  16. data/items/[item].tsx のデフォルト値。
    export const data が自動的に /items/:item にマッピングされる。

    View Slide

  17. dodai での解決 ②
    React の Server Renderer で HTML を出⼒
    - renderToStaticMarkup で完結する世界
    - Hydration ⽤のコードも出現しない
    原則ランタイムの環境は提供しない
    - ランタイムJSが必要な場合は別途環境構築を要求
    - 脱出ハッチが必要になるケースは SSG 以上の要件と
    認定

    View Slide

  18. 実際の renderToStaticMarkup のコード。
    import したメタデータを props/children として流し込んでいる。

    View Slide

  19. dodai での解決 ③
    最⼩限の機能
    - Path-based routing
    - Dev server
    - Hot reload
    最⼩限の依存
    - glob や chokidar など⼗分に枯れた10個のみ

    View Slide

  20. 最新版(v0.5.4)の最新の依存関係。
    基本的には小粒でドラスティックな変化のないパッケージが並んでいる。

    View Slide

  21. - ⾃⼰紹介
    - @potato4d/dodai の概要
    - 既存ソリューションの課題感とアンサー
    - ビルドの仕組み
    - おわりに
    ■ Agenda

    View Slide

  22. dodaiの利⽤技術
    コアとなる技術 dodai 内で書かれている技術(ライブラリ⾮依存)
    コア機能を補助するためのライブラリ
    chokidar
    Commander.js
    consola
    Express
    glob
    fs-extra
    HotReload
    boilerplate

    View Slide

  23. dodaiのアーキテクチャ(build編)
    Main Process
    .tsx
    Original Files
    HTMLファイル
    最終成果物
    (./dist/*)
    画像や robots など
    Reactのための中間成果物
    (./.dodai-build/*)
    .js
    File System
    Program

    View Slide

  24. dodaiのアーキテクチャ(build編)
    Main Process
    .tsx
    Original Files
    ① Compiler API で Call
    HTMLファイル
    最終成果物
    (./dist/*)
    画像や robots など
    File System
    Program
    Reactのための中間成果物
    (./.dodai-build/*)
    .js

    View Slide

  25. dodaiのアーキテクチャ(build編)
    Main Process
    .tsx
    Original Files
    ① Compiler API で Call
    ② トランスパイル
    HTMLファイル
    最終成果物
    (./dist/*)
    画像や robots など
    File System
    Program
    Reactのための中間成果物
    (./.dodai-build/*)
    .js

    View Slide

  26. dodaiのアーキテクチャ(build編)
    Main Process
    .tsx
    Original Files
    ① Compiler API で Call
    ② トランスパイル ③ 成果物を書き出し HTMLファイル
    最終成果物
    (./dist/*)
    画像や robots など
    File System
    Program
    Reactのための中間成果物
    (./.dodai-build/*)
    .js

    View Slide

  27. dodaiのアーキテクチャ(build編)
    Main Process
    .tsx
    Original Files
    ① Compiler API で Call
    ② トランスパイル ③ 成果物を書き出し
    ④ rendertoStaticMarkup
    HTMLファイル
    最終成果物
    (./dist/*)
    画像や robots など
    File System
    Program
    Reactのための中間成果物
    (./.dodai-build/*)
    .js

    View Slide

  28. dodaiのアーキテクチャ(build編)
    Main Process
    .tsx
    Original Files
    ① Compiler API で Call
    ② トランスパイル ③ 成果物を書き出し
    ④ rendertoStaticMarkup
    ⑤ JS として import
    HTMLファイル
    最終成果物
    (./dist/*)
    画像や robots など
    File System
    Program
    Reactのための中間成果物
    (./.dodai-build/*)
    .js

    View Slide

  29. dodaiのアーキテクチャ(build編)
    Main Process
    .tsx
    Original Files
    ① Compiler API で Call
    ② トランスパイル ③ 成果物を書き出し
    ④ rendertoStaticMarkup
    ⑤ JS として import
    ⑥ string で結果を返却
    HTMLファイル
    最終成果物
    (./dist/*)
    画像や robots など
    File System
    Program
    Reactのための中間成果物
    (./.dodai-build/*)
    .js

    View Slide

  30. dodaiのアーキテクチャ(build編)
    Main Process
    .tsx
    Original Files
    ① Compiler API で Call
    ② トランスパイル ③ 成果物を書き出し
    ④ rendertoStaticMarkup
    ⑤ JS として import
    ⑥ string で結果を返却
    ⑦ HTML を書き出し ⑧ static/ をコピー
    HTMLファイル
    最終成果物
    (./dist/*)
    画像や robots など
    File System
    Program
    Reactのための中間成果物
    (./.dodai-build/*)
    .js

    View Slide

  31. dodaiのアーキテクチャ(watch編)
    HTML Server
    (http://localhost:5432)
    ᶃɺᶄͷॳճ࣮ߦޙ͸ᶅʙᶊ͕ࣗಈతʹ܁Γฦ͞ΕΔɻ
    αʔόʔ಺Ͱ׬݁͢Δॲཧ
    ϒϥ΢βͱαʔόʔͷॲཧ
    Main Process
    HotReload Server
    (http://localhost:10020)

    View Slide

  32. dodaiのアーキテクチャ(watch編)
    リクエストごとに最新のHTMLを配信
    HotReload Server
    (http://localhost:10020)
    ᶃɺᶄͷॳճ࣮ߦޙ͸ᶅʙᶊ͕ࣗಈతʹ܁Γฦ͞ΕΔɻ
    αʔόʔ಺Ͱ׬݁͢Δॲཧ
    ϒϥ΢βͱαʔόʔͷॲཧ
    Main Process
    HTML Server
    (http://localhost:5432)

    View Slide

  33. dodaiのアーキテクチャ(watch編)
    リクエストごとに最新のHTMLを配信
    .tsx
    ① chokidarで監視
    ᶃɺᶄͷॳճ࣮ߦޙ͸ᶅʙᶊ͕ࣗಈతʹ܁Γฦ͞ΕΔɻ
    αʔόʔ಺Ͱ׬݁͢Δॲཧ
    ϒϥ΢βͱαʔόʔͷॲཧ
    Main Process
    HTML Server
    (http://localhost:5432)
    HotReload Server
    (http://localhost:10020)

    View Slide

  34. dodaiのアーキテクチャ(watch編)
    リクエストごとに最新のHTMLを配信
    .tsx
    ① chokidarで監視
    ② ブラウザからアクセス
    ᶃɺᶄͷॳճ࣮ߦޙ͸ᶅʙᶊ͕ࣗಈతʹ܁Γฦ͞ΕΔɻ
    αʔόʔ಺Ͱ׬݁͢Δॲཧ
    ϒϥ΢βͱαʔόʔͷॲཧ
    Main Process
    HTML Server
    (http://localhost:5432)
    HotReload Server
    (http://localhost:10020)

    View Slide

  35. dodaiのアーキテクチャ(watch編)
    リクエストごとに最新のHTMLを配信
    .tsx
    ① chokidarで監視
    ② ブラウザからアクセス
    ③ /subscribe にポーリング
    ※ HTMLϑΝΠϧʹؚ·ΕΔॲཧ
    ᶃɺᶄͷॳճ࣮ߦޙ͸ᶅʙᶊ͕ࣗಈతʹ܁Γฦ͞ΕΔɻ
    αʔόʔ಺Ͱ׬݁͢Δॲཧ
    ϒϥ΢βͱαʔόʔͷॲཧ
    Main Process
    HTML Server
    (http://localhost:5432)
    HotReload Server
    (http://localhost:10020)

    View Slide

  36. dodaiのアーキテクチャ(watch編)
    リクエストごとに最新のHTMLを配信
    .tsx
    ① chokidarで監視
    ② ブラウザからアクセス
    ③ /subscribe にポーリング
    ※ HTMLϑΝΠϧʹؚ·ΕΔॲཧ
    ④ 変更検知後ビルド
    ᶃɺᶄͷॳճ࣮ߦޙ͸ᶅʙᶊ͕ࣗಈతʹ܁Γฦ͞ΕΔɻ
    αʔόʔ಺Ͱ׬݁͢Δॲཧ
    ϒϥ΢βͱαʔόʔͷॲཧ
    Main Process
    HTML Server
    (http://localhost:5432)
    HotReload Server
    (http://localhost:10020)

    View Slide

  37. dodaiのアーキテクチャ(watch編)
    リクエストごとに最新のHTMLを配信
    .tsx
    ① chokidarで監視
    ② ブラウザからアクセス
    ③ /subscribe にポーリング
    ※ HTMLϑΝΠϧʹؚ·ΕΔॲཧ
    ④ 変更検知後ビルド
    ⑤ 更新を通知
    ᶃɺᶄͷॳճ࣮ߦޙ͸ᶅʙᶊ͕ࣗಈతʹ܁Γฦ͞ΕΔɻ
    αʔόʔ಺Ͱ׬݁͢Δॲཧ
    ϒϥ΢βͱαʔόʔͷॲཧ
    Main Process
    HTML Server
    (http://localhost:5432)
    HotReload Server
    (http://localhost:10020)

    View Slide

  38. dodaiのアーキテクチャ(watch編)
    リクエストごとに最新のHTMLを配信
    .tsx
    ① chokidarで監視
    ② ブラウザからアクセス
    ③ /subscribe にポーリング
    ※ HTMLϑΝΠϧʹؚ·ΕΔॲཧ
    ④ 変更検知後ビルド
    ⑤ 更新を通知
    ⑥ HTTP Response を返却
    ᶃɺᶄͷॳճ࣮ߦޙ͸ᶅʙᶊ͕ࣗಈతʹ܁Γฦ͞ΕΔɻ
    αʔόʔ಺Ͱ׬݁͢Δॲཧ
    ϒϥ΢βͱαʔόʔͷॲཧ
    Main Process
    HTML Server
    (http://localhost:5432)
    HotReload Server
    (http://localhost:10020)

    View Slide

  39. dodaiのアーキテクチャ(watch編)
    リクエストごとに最新のHTMLを配信
    .tsx
    ① chokidarで監視
    ② ブラウザからアクセス
    ③ /subscribe にポーリング
    ※ HTMLϑΝΠϧʹؚ·ΕΔॲཧ
    ④ 変更検知後ビルド
    ⑤ 更新を通知
    ⑥ HTTP Response を返却
    ⑦ ポーリング終了検知後再読み込み
    ᶃɺᶄͷॳճ࣮ߦޙ͸ᶅʙᶊ͕ࣗಈతʹ܁Γฦ͞ΕΔɻ
    αʔόʔ಺Ͱ׬݁͢Δॲཧ
    ϒϥ΢βͱαʔόʔͷॲཧ
    Main Process
    HTML Server
    (http://localhost:5432)
    HotReload Server
    (http://localhost:10020)

    View Slide

  40. dodaiのアーキテクチャ(watch編)
    リクエストごとに最新のHTMLを配信
    .tsx
    ① chokidarで監視
    ② ブラウザからアクセス
    ③ /subscribe にポーリング
    ※ HTMLϑΝΠϧʹؚ·ΕΔॲཧ
    ④ 変更検知後ビルド
    ⑤ 更新を通知
    ⑥ HTTP Response を返却
    ⑦ ポーリング終了検知後再読み込み
    ⑧ リロードによって再度アクセス
    ᶃɺᶄͷॳճ࣮ߦޙ͸ᶅʙᶊ͕ࣗಈతʹ܁Γฦ͞ΕΔɻ
    αʔόʔ಺Ͱ׬݁͢Δॲཧ
    ϒϥ΢βͱαʔόʔͷॲཧ
    Main Process
    HTML Server
    (http://localhost:5432)
    HotReload Server
    (http://localhost:10020)

    View Slide

  41. IUUQTEQPUBUPENFFOUSZNJOJNBMIPUSFMPBE

    View Slide

  42. - ⾃⼰紹介
    - @potato4d/dodai の概要
    - 既存ソリューションの課題感とアンサー
    - ビルドの仕組み
    - おわりに
    ■ Agenda

    View Slide

  43. おわりに
    - dodai もいくつかのWebサイトで使っていたもの切り出して誕⽣した
    - 当時は React SSG + TypeScript + HotReload のみで CLI などはなし
    - それを ts-node で実⾏していた
    - ⼩さな要件を満たすためなら要件も依存関係も少なくなる
    - 乗っかる側もリスクが少ない基盤になるのでコミュニティとして広がるかも

    View Slide

  44. 理想のSSGを
    ⼀緒に考えよう
    理想のSSGを
    ⼀緒に考えよう

    View Slide