Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
プライベートクラウドの コンソール画面を Next.jsのApp Routerで フルリプレイスした話 株式会社サイバーエージェント Shuta Hirai
Slide 2
Slide 2 text
1. CIUフロントエンドについて 2. なぜNext.jsを使うのか 3. App Router化までの道のり 4. 結果と所感 5. 今後の展望
Slide 3
Slide 3 text
Shuta Hirai 株式会社サイバーエージェント グループIT推進本部 CyberAgent group Infrastructure Unit(CIU) フロントエンド寄りエンジニア Meguro.es 主催 GitHub : https://github.com/shuta13 X(Twitter) : https://twitter.com/did0es
Slide 4
Slide 4 text
CIUフロントエンドに ついて
Slide 5
Slide 5 text
インフラの組織でフロントエンド?
Slide 6
Slide 6 text
CIUフロントエンドのタスク =
Slide 7
Slide 7 text
CIUフロントエンドのタスク = プライベートクラウドや その関連サービスの開発・運用
Slide 8
Slide 8 text
CIUフロントエンドの役割 =
Slide 9
Slide 9 text
CIUフロントエンドの役割 = Web UIの提供で利用者層を増加
Slide 10
Slide 10 text
CLIツールのWeb UIの開発 (aws, gcpなどのサービスの画面を 想像してください)
Slide 11
Slide 11 text
事例 - AKE
Slide 12
Slide 12 text
事例 - ML Platform
Slide 13
Slide 13 text
事例 - IAM
Slide 14
Slide 14 text
チーム体制
Slide 15
Slide 15 text
チーム体制 =マネージャーx2・エンジニアx2
Slide 16
Slide 16 text
サービス:エンジニア =
Slide 17
Slide 17 text
サービス:エンジニア = 10 : 1(サービス数は20↑個)
Slide 18
Slide 18 text
/(^o^)\
Slide 19
Slide 19 text
フロントエンドエンジニアが少ない →
Slide 20
Slide 20 text
フロントエンドエンジニアが少ない →フロント以外が開発に入る あるいは外注
Slide 21
Slide 21 text
フロントエンドエンジニアが少ない →フロント以外が開発に入る あるいは外注 →それでもサービスの質を 落としたくない
Slide 22
Slide 22 text
サービスの品質維持の取り組み ・コードの自動生成←前回 ・Next.jsの採用と追従 ・クリーンアーキテクチャによる抽象化 ・UI・APIの型などを含むSDKの開発 など
Slide 23
Slide 23 text
speakerdeck 前回(コードの自動生成)
Slide 24
Slide 24 text
サービスの品質維持の取り組み ・コードの自動生成 ・Next.jsの採用と追従←今回 ・クリーンアーキテクチャによる抽象化 ・UI・APIの型などを含むSDKの開発 など
Slide 25
Slide 25 text
なぜNext.jsを使うのか
Slide 26
Slide 26 text
※特に関係ないです https://leerob.io/blog/using-nextjs
Slide 27
Slide 27 text
CIUフロントエンドチームの方針
Slide 28
Slide 28 text
誰もが一定の品質で Cycloud のサービスのWeb UIを 実装できるようにする
Slide 29
Slide 29 text
Web技術からCycloudに 必要なものを取捨選択しつつ Web技術の進化に追従する
Slide 30
Slide 30 text
Next.jsの採用と追従 Next.jsを使うワケ ・Next.js自体がReactのベストプラクティスを体現しているため ・使えば誰もがベストプラクティスを実践できる ・SSRやRouting、ビルドで手を抜くためだけのFWではなくなった ・Reactの破壊的変更をある程度吸収してくれる ・ベンダーロックインが...とか言われるが... ・Vercel以外のコンテナ・サーバーレス等で困らない程度には動く
Slide 31
Slide 31 text
Next.js is a shock absorber Next.jsは「Reactの緩衝材」として使う ・あくまでReactのAPIの抽象化層とみなす ・当然使わない機能もある ・例えば ・fetch(クライアントサイドfetchで代用) ・middlewareによるproxy(API Routesかnext.config.jsで代用) ・Next.jsを知らない人が見て一目で分かるかをもとに取捨選択
Slide 32
Slide 32 text
Next.jsの運用 CIUではNext.jsサーバーをCloud Run上に立てている ・なるべくCSRに寄せているので、これで十分 確かにVercelが欲しくなる場面もあるが、限定的 ・Pages Router時代のISRなどのNext.jsの機能 ・やろうと思えば他のベンダーでも出来る ・CI/CDの最適化 ・CIUではmyshoes(self-hosted runner)で改善を図っている ・Edge Network ・CFなど、CDNで賄える
Slide 33
Slide 33 text
App Router化までの道のり
Slide 34
Slide 34 text
App Router化の動機 ・フロントエンドの技術的成長 ・ReactのRSCに対する知見を深め、新たなベストプラクティスを構築する ・Next.jsを介して使うことで、RSCの大幅な変更に追従しやすく ・Dynamic Renderingから、Static Rendering前提に変わった ・CSR前提のWeb UIにとっては都合が良い ・Next.jsがApp Router前提の機能開発に寄せ始めた ・Pages Routerからは使えないAPIが出始めた
Slide 35
Slide 35 text
App Router化するサービス Cycloud IAMというCycloudの統合認証基盤のWeb UI ・Cycloudユーザー向け ・既にCLIが整備されている ・ちょうどPages Routerで作りかけのWeb UIがあった
Slide 36
Slide 36 text
🏃App Router化開始🏃
Slide 37
Slide 37 text
next v13へ更新 v12をからv13へ更新 ・v13移行向けのcodemodを利用 ・変換漏れは手作業で修正 reactとreact-domもv16からv18へ更新 ・import React from “react” を codemod で抹消
Slide 38
Slide 38 text
pages to app migrating-from-pages-to-app を参考に進める ・空の/appを作成し、そこにファイルを移動させる ・/pagesと/appは共存できるので↑が楽 ・_documentと_appは残したままで進め、最後にRoot Layoutに移行
Slide 39
Slide 39 text
“use client” ディレクティブ追加 pages to app中に “use client” が無い旨のエラーが出るので手作業で修正 ・シェルなどで全TSXファイルに機械的に追加はしない ・パフォーマンスの観点から積極的にSCを利用する ・CCはSCを含めないので、適宜propsにchildrenを追加する
Slide 40
Slide 40 text
RSCに対応していないライブラリ ライブラリによってはRSCに対応していないReactで書かれている ・一旦importして、”use client” をつけて re-export ・ちなみにMUIとNextUIをこれで使っていた ・後者の更新がつらいので、内製のUIライブラリに移行中 ・Testingのため、RSCではないReact Componentに分離してテストしてから輸入
Slide 41
Slide 41 text
getInitialPropsの移行 一部のページで使用していたため、Next.jsのfetchで置き換えた ・が、キャッシュの扱いが微妙なので廃止 ・基本CSRで、SWRをラップしたHookを用いてクライアントサイドでfetch ・ちなみにクライアントfetchはNext.jsによって拡張されない ・SWRに依存したくなければuseEffect内でfetchすればいい ・状態管理にSWRを使っている & fetchの重複排除などがほしいので APIを叩く用途にも使用した
Slide 42
Slide 42 text
API Routes to Route Handlers pages/api から app/XXX/route に移行 ・書き方が若干変わるので、手作業で修正 ・認証に使用しているnext-authも移行 ・next-auth側でApp Routerは 対応済み
Slide 43
Slide 43 text
HTTP Proxy Middlewareやめる CORSを避けるための next-http-proxy-middleware が使えなくなった ・Route Handlersではres, reqがimmutableになった ・上記のHTTP Proxyは2つを上書きする ・そもそもNext.jsのconfigで出来た
Slide 44
Slide 44 text
の移行 next/head を用いた記述を移行 ・`export const metadata` をページ内に記述 ・UIの実装に専念できるようになった ・その反面、HTMLらしい文法からは離れてしまった ・JS Objectなので宣言的さは失われてないが...
Slide 45
Slide 45 text
i18n対応 useLocale というカスタムフックが useRouter の仕様変更で使えなくなった ・localeがrouterに乗らなくなった
Slide 46
Slide 46 text
Middlewareを用いてみる
Slide 47
Slide 47 text
Middlewareでリダイレクトする場合以外への対応 ・言語のSwitch UIなど ・useContextをラップしたものに書き換え ・Provider経由で辞書を渡して、useLocaleでreadする useLocaleを変更
Slide 48
Slide 48 text
i18n対応(断念) エラーページ(404, 500など)がi18n対応できない ・https://github.com/vercel/next.js/discussions/12477 ・優先度は低いが、対応できないならそもそも移行しないほうが良い判断に ・app/[lang]にするパターンより、localStorageに持ったほうが楽そう ・i18nライブラリが成熟するのを待って良い
Slide 49
Slide 49 text
結果と所感
Slide 50
Slide 50 text
バンドル結果 (nextのbundle analyzerで計測) Pages Router製サービス(AKE) ・クライアント:サーバー = 2.45MB:2.23MB 計 4.67MB App Router製サービス(IAM) ・クライアント:サーバー = 2.57MB:3.4MB 計 5.97MB 全体の容量は増えているが、App Routerでクライアント < サーバーができた →増えた要因は内製したUIなどのSDK →だが、ある程度サーバーサイドに持っていけた
Slide 51
Slide 51 text
Lighthouse (3回計測した平均スコア 計測対象はTOPのリスト表示ページ) Pages Router製サービス(AKE) ・Perf:A11y:BP:SEO = 84:74:100:91 App Router製サービス(IAM) ・Perf:A11y:BP:SEO = 99:87:100:82 参考程度ではあるが、パフォーマンスが向上した →Speed Indexが大幅に改善(4.8s→0.4s) →RSCというより、Static Renderingの効果かもしれない
Slide 52
Slide 52 text
良かった点 ・フォルダの表現力が向上した ・Route GroupsでUIワイヤーを構成に反映 ・Private Foldersでページに閉じたコンポーネント・API作成 ・RSCの使い方や仕組みをインプットできた ・なにそれおいしいの?レベルから脱却 ・べスプラも(多少)構築できた ・”use client”を入れる位置を限定する ・Server Componentであれば容量大きめのライブラリを import できるなど
Slide 53
Slide 53 text
イマイチな点 ・ライブラリの追従 ・API Routesにがっつり依存しているライブラリ(next向けhttp proxyなど)は 軒並み動かなかった ・testing-libraryでTestingもできない ・パフォーマンス ・(fetch 向けに)force-dynamicをつけると悪化した ・↑fetchのcacheを無効化するが、ページ全体がDynamic Renderingされていた ・i18n対応 ・エラー系のページどうするの
Slide 54
Slide 54 text
今後の展望
Slide 55
Slide 55 text
やりたいこと ・fetchの仕組みの調査 ・(ISRなら)キャッシュが危険そう & 従来のfetchと異なる動きをするため使ってない ・が、正体がわかれば使って良さそう ・Server Actionsのべスプラの考察 ・Next.js v14への更新 ・create-next-app を内製 ・CLIからコマンド1つでWeb UIを作れるように ・Goで書いてます
Slide 56
Slide 56 text
次回 次回(いつ?)はフロントエンドエンジニア、あるいはエンジニア以外でも Web UIを実装できる化するためのエンジニアリングの話をします ・✅ コードの自動生成 ・✅ Next.jsの採用と追従 ・クリーンアーキテクチャによる抽象化 ・UI・APIの型などを含むSDKの開発←メイン
Slide 57
Slide 57 text
ご清聴ありがとうございました