Upgrade to Pro — share decks privately, control downloads, hide ads and more …

控えめな App Router と持続可能な開発 - PWA Night vol.59

Ayumu Sato
January 17, 2024

控えめな App Router と持続可能な開発 - PWA Night vol.59

Ayumu Sato

January 17, 2024
Tweet

More Decks by Ayumu Sato

Other Decks in Programming

Transcript

  1. 控えめな App Router と持続可能な開発
    2024.01.17 @ahomu
    PWA Night vol.59 〜フロントエンド設計の振り返り〜

    View full-size slide

  2. @ahomu - Ayumu Sato
    株式会社 over
    fl
    ow
    副業・転職サービス O
    ff
    ers 開発、VPoE
    前の職場: 緑のメガベンでテックリード、マネージャー、⼈事など
    前々職場: Web システムの受託会社で零細フルスタック開発

    View full-size slide

  3. みなさん App Router 楽しんでますか

    View full-size slide

  4. 使うパーツを選べば控えめにも使えそう、という話
    メンタルモデルやプラクティスの更新は時間かかりますからね

    View full-size slide

  5. Agenda
    話の流れ、スライドは⽂字多めですmm
    1.開発コンテキスト
    2.設計と選定
    3.控えめな App Rouer
    4.持続可能な開発

    View full-size slide

  6. ։ൃίϯςΩετ

    View full-size slide

  7. Context
    ここ数年のスタートアップでよく⾒るやつ
    • 中⻑期の QCD とユーザー体験の改善を狙ったリプレースプロジェクト
    • Ruby on Rails モノリスからフロントエンド部分を剥がして置き換える
    • ログインユーザーと⾮ログインユーザーが混在して利⽤する画⾯
    • 今後はログインユーザー向けアプリケーション等の置き換え予定もある
    • Ruby on Rails が提供する GraphQL とその裏側にある既存資産の流⽤が前提

    View full-size slide

  8. Team
    とことん Rails Way で⾏くことも検討したのですが諸事情が...(・x・)
    • 既存の技術スタックは Ruby on Rails + Vue.js + jQuery
    • Ruby と RoR 上等、JavaScript と Vue 程々といったメンバーが多め
    • 別プロダクトでは先⾏して現代の技術スタックを⽀持
    • O
    ff
    ers MGR (SaaS) : Next.js Pages Router を利⽤した SPA
    • オウンドメディア群 : monorepo 管理で Astro ベース量産(共通化 & コピペ)
    • Next.js に触れること⾃体は意気軒昂
    • Vue.js の責ではないが既存コードの腐敗が厳しく前⽅に脱出したい空気

    View full-size slide

  9. ઃܭͱબఆ

    View full-size slide

  10. Overview
    局所影響のあるログイン判定、ユーザー依存情報の取得はクライアントサイドで⾮同期にやる
    User
    ① HTML リクエスト
    ② ユーザー⾮依存情報 (gql)
    ③ HTML レスポンス
    ④ ユーザー依存情報 (gql)
    CloudFront

    View full-size slide

  11. Migration plan
    1ページずつ順番にゆっくりやっています
    ECS
    Lamba
    CloudFront ELB RDS
    ※1 実際は1度インターネットに出ています (略図)
    ※2 ELB の表現⼒を超えているので nginx 先⽣にお願いしています
    ※1
    User
    ※2
    特定のパスへのリクエスのみ nginx で
    Lambda 上の Next.js 宛てにリバースプロキシ
    リプレースの適⽤範囲を段階的に拡げていく

    View full-size slide

  12. Web framework
    最近はどれも良くできてますなぁ
    • Next.js、Qwik City、Remix、SvelteKit、Vite ベースの⼿作りを⽐較検討
    • うーん・・・
    • 社内エンジニアへの要求知識の増分 (特に React 以外)
    • フレームワークの基本構成 (スターター類) の⾒通しの良さ、簡潔さ
    • ビルド後の成果物ファイルサイズの多寡
    • クライアントサイドバンドルのファイルサイズを絞り込む機構の有無

    View full-size slide

  13. うん、⻑いもの (Next.js) に巻かれよう!
    今回の要件はともかく他のアプリもあるので投資 投資

    View full-size slide

  14. Repository
    無難にやってます
    • サービス内の複数アプリを管理する monorepo 構造
    • Turborepo のスターターを踏襲
    • apps/*
    • アプリ置き場、今後増えるが⼀応 Next.js に限らない
    • packages/*
    • Design System 実装ほか共通ライブラリ、設定など

    View full-size slide

  15. • src
    • __generated__
    • app
    • components
    • features
    • providers
    • utils
    • acme-feature
    • components
    • hooks
    • providers
    • utils
    • AcmeComponent
    • AcmeComponent.module.css
    • AcmeComponent.stories.tsx
    • AcmeComponent.test.tsx
    • AcmeComponent.tsx
    • index.tsx
    app/**/src features/** components/*
    アプリ内共通層 関⼼別の分類層 個々のコンポーネント
    App Router
    graphql-codegen
    components
    gql Fragment
    hooks
    App Router と⼼中し切っていない構造... 200⾏超えたら⼦コンポーネントに分割していく感覚

    View full-size slide

  16. 詳しくは zenn 記事のほうを参照してください :)
    • Next.js に限らないレイヤリング
    • "上から順に辿って分かる"が⼤切
    • App Router とズブズブなら...
    • app 以下にページ固有要素を集約
    • 共通パーツは _shared に分類・整理
    Directories in app

    View full-size slide

  17. Others
    その他いろいろ
    • Styling
    • Mocking
    • Testing
    • UI Inventory
    • GraphQL
    • State + Fetch
    CSS Modules
    Resolver 先⾏でやりくりにつき省略、テストのみ msw 使⽤
    vitest + testing-library + msw + happy-dom
    シンプルに Storybook、アドオンは最⼩限
    GraphQL Code Generator + client-preset
    TanStack Query + graphql-request + React.cache

    View full-size slide

  18. ߇͑Ίͳ
    "QQ3PVUFS

    View full-size slide

  19. “おれのかんがえたさいきょう” は絶対詰む ∕(^o^)\

    View full-size slide

  20. とりあえず普通の Web アプリ作りたいんだよなぁ

    View full-size slide

  21. Normally
    普通というかトラディショナルというか…
    • サーバーサイド (オリジン) が HTML を返す
    • CDN (エッジ) が HTML をキャッシュする
    • ブラウザが HTML を受け取る
    • クライアントサイドの JavaScript バンドルが UI を動かす

    View full-size slide

  22. hmm...
    オリジンがもりもり仕事するログイン前提の SaaS だと App Router + RSC 全⼒設計たのしそう
    • いくつかの機能は要求するメンタルモデルの変化が⼤きい (特に古い RoR ⽐)
    • Caching features
    • next/link の推奨 → SPA の半強制 (これは Pages Router もだったか?)
    • RSC + Suspense
    • RSC Payload
    • Server Actions 等の境界 etc...

    View full-size slide

  23. よっしゃ、ほどほどに使おう
    必要になるまで App Router の全⼒は持ち越し、Keep It Simple, Stupid

    View full-size slide

  24. 詳しくは zenn 記事のほうを参照してください :)
    • 各種の内部 Cache 無効化
    • soft navigation を禁⽌
    • page.tsx ≒ getServerSideProps
    • RSC + Suspense は不使⽤
    • middleware で Cache-Control
    Details

    View full-size slide

  25. App Router らしくないが従来知識でも⾒れば分かる
    msw や storybook との互換性問題やテスト周りの障害も回避!

    View full-size slide

  26. We ♥ Next.js
    Remix に浮気したいとか⾔わない...よ?
    • App Router の全⼒でなくてもフレームワークとしての基盤は有⽤
    • レイアウト、ルーティング、最適化、ビルド周り⼀式、公式プラグイン etc
    • チームでは Next.js と React と TypeScript の基本から固めたい
    • 便利なサブセットは必要になったら都度チームとして取り⼊れる

    View full-size slide

  27. ࣋ଓՄೳͳ։ൃ

    View full-size slide

  28. ⚠ ここから思想が偏ります

    View full-size slide

  29. https://w3c.github.io/sustyweb/

    View full-size slide

  30. 3.17 Manage Dependencies Appropriately
    "only using libraries where necessary" 本当に必要なものだけを管理しましょう、って
    • Environmental
    • 開発者のマシンは、必要のないパッケージのインストールやレンダリングにエネルギーを浪費す
    る必要がない。
    • Security
    • サードパーティのコードには、バグやセキュリティ上の問題が含まれている可能性があります。
    パッケージを常に最新の状態に保ち、サードパーティ・ライブラリの使⽤数を減らすことで、セ
    キュリティ上の⽋陥が発⽣する可能性を減らすことができます。
    • Performance
    • クライアントサイドのJavaScriptを減らすと、通常ウェブサイトが速くなります。

    View full-size slide

  31. 依存の肥⼤化は開発の持続可能性を損ねる

    View full-size slide

  32. Bloated dependence
    Next.js などの⼤物が引き連れてくる依存ツリーがそもそも多い/⼤きいという話はある
    • 依存パッケージのアップデート
    • アップデートするためのアップデート
    • アップデートするためのアップデートのためのアップデート
    • バージョン整合性パズルがしばしば開催される
    • クライアントサイドバンドルが⼤きくなる (devDependencies は限りでない)
    • サプライチェーン毒まんじゅうの当たり判定が増える

    View full-size slide

  33. プリミティブなパーツをシンプルに使うことを優先
    過度に禁欲的にはならずとも常に⾃問していくスタイル

    View full-size slide

  34. Prefer primitives
    異論は認める、素朴に書くほうが GPT 等の AI によるコーディング⽀援を受けやすいとかはある
    • classnames パッケージを⼊れずに [].join で済ます
    • tailwind や CSS in JS もいらない、Next.js の CSS Modules で事⾜りる
    • IntersectionObserver や matchMedia のラッパーも不要
    • Storybook はあくまで UI インベントリ、余計なことしない
    • アクセシブルな UI 各種 → react-aria 最⾼!!
    • 凝った Carousel UI、凝った Combobox 各種 → ぐぬぬ...

    View full-size slide

  35. package.json
    必要最⼩限の依存を努めている (storybook や uni
    fi
    ed 関連は外出しされています :P )
    "dependencies": {
    "@bugsnag/js": "7.22.2",
    "@next/bundle-analyzer": "14.0.2",
    "@next/third-parties": "14.0.2",
    “@my-prj/md2html": "workspace:*",
    “@my-prj/ui": "workspace:*",
    "@opentelemetry/api": "1.7.0",
    "@opentelemetry/sdk-trace-base": "1.19.0",
    "@tanstack/react-query": "5.0.0",
    "@tanstack/react-query-devtools": "5.0.1",
    "encoding": "0.1.13",
    "graphql-request": "6.1.0",
    "keen-tracking": "5.0.1",
    "next": "14.0.2",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "valibot": "0.20.1"
    },
    "devDependencies": {
    "@graphql-codegen/cli": "5.0.0",
    "@graphql-codegen/client-preset": "4.1.0",
    "@my-prj/eslint-config-offers": "workspace:*",
    “@my-prj/prettier”: "workspace:*",
    "@my-prj/stylelint-config-offers": "workspace:*",
    "@my-prj/test-utils": "workspace:*",
    "@my-prj/tsconfig": "workspace:*",
    "@vitejs/plugin-react": "4.2.0",
    "eslint": "8.47.0",
    "happy-dom": "12.10.3",
    "postcss-nesting": "12.0.1",
    "prettier": "3.0.3",
    "schema-dts": "1.1.2",
    "stylelint": "15.11.0",
    "typescript": "5.2.2",
    "vitest": "1.0.1"
    }, @types/

    は割愛しています

    View full-size slide

  36. In my opinion...
    偏った思想の中⼼です
    • Next.js のクライアントサイドバンドルだけでも既に⼤きい
    • 「あったら便利」 程度では⻭⽌めがきかなくなる
    • 糖⾐構⽂程度の開発者体験のためにユーザー体験を毀損してはならない
    • 依存関係を増やせば増やすほど苦労するのは未来の誰か
    • 主要ライブラリはそれぞれの理想を求めてダイナミックに進化する
    • 各依存先の理想と理想の折り合いに疲弊するのがフロントエンドの近代史

    View full-size slide

  37. ⻄表島にいたヤギです
    • App Router は控えめにも使える
    • 使い切らない導⼊戦略も
    • 依存は⼤事だよ〜
    • よ〜く考えよ〜
    • 本当に必要か常に⾃問したい
    まとめ

    View full-size slide

  38. ご清聴ありがとうございました :)

    View full-size slide