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

マイグレーションコード自作して File-Based Routing に自動移行!! ~250...

Cut0
August 27, 2024

マイグレーションコード自作して File-Based Routing に自動移行!! ~250 ページの歴史的経緯を添えて~

WinTicket Webチームは、ユーザーが操作するアプリケーションだけでなく、社員が操作する管理画面の開発も行っています。 管理画面では、各社員の権限を基に、適切な画面の閲覧権と操作権を管理しています。

しかし、経年劣化・歴史的経緯による権限管理処理の複雑さや、コードベースのルーティング管理の煩雑さが課題となっていました。

今回はマイグレーションコードを自作して、250 ページにわたる画面を React Router から TanStack Router に全て置き換えた背景や手法をお話します。

Cut0

August 27, 2024
Tweet

Other Decks in Programming

Transcript

  1. 加藤 零 - kato, rei C 2023年 株式会社サイバーエージェント新卒入P C 株式会社

    WinTicket 所# C # Web Speed Hackathon 2024 作問者 自己紹介 @cut0_ @cut0
  2. 3 公営競技ネット投票サービ 3 競輪/オートレー 3 2019年4月リリー 3 市場シェアNo.1 #React #Fastly

    #Go #Kubernetes #Flutter #Cloud Run #Google Cloud #TypeScript #TanStack Query WINTICKET について
  3. WINTICKET Web チームについて h チームメンバー 5 T h サービス本体の開発 +

    Web に関連する社内ツールの開G h WINTICKE7 h 管理画( h ダッシュボー h その他内製ツール
  4. WINTICKET Web チームについて ) チームメンバー 5 3 ) ) WINTICKE'

    ) ) ダッシュボー ) その他内製ツール サービス本体の開発 + Web に関連する社内ツールの開q 管理画I →今回話す対象
  5. TanStack Router 移行背景 s 管理面はクラシックな SPA で構成されていて SSR を行っていなe s

    GCS に HTML + JS + CSS をホスティングするシンプルな構“ s ルーティングライブラリの高度な機能を必要としなe s TanStack Router も最低限のルーティング機能だけを利用 前提
  6. TanStack Router 移行背景 h React Router v5 を利T h 250

    ページに及ぶルーティングを1つのファイルで管理R h RoleRoute, ProtectedRoute の混4 h 違いについては後述 障壁
  7. TanStack Router について ~ルーティング~ TanStack Router は下記の二種類のルーティング手段を提供している File-Based Routin —

    ディレクトリ・ファイルの構造に応じてルーティングルールを設 — src/pages/hoge/$fuda/index.tsx -> /hoge/:fuga にマッt — src/pages/hoge/$fuda/-Example.tsx -> - プレフィックスはルーティングに含まれなc — 他にも様々なルールがある ( ) 参考 Code Based Routin — 以前の管理面と同様にコードにルーティングルールを記載する
  8. TanStack Router について ~ルーティング~ TanStack Router は下記の二種類のルーティング手段を提供している File-Based Routin —

    ディレクトリ・ファイルの構造に応じてルーティングルールを設 — src/pages/hoge/$fuga/index.tsx -> /hoge/:fuga にマッt — src/pages/hoge/$fuga/-Example.tsx -> - プレフィックスはルーティングに含まれなc — 他にも様々なルールがある ( ) 参考 Code Based Routin — 以前の管理面と同様にコードにルーティングルールを記載する →ルーティングファイル肥大化問題を解決するため採用
  9. AST の解析について AST の解析には jscodeshift を利用 ‡ JavaScript の codemod、TypeScript

    でも利用可i ‡ 左図のように AST を見ながらコーディングするのがq ‡ 類似のライブラリでは ts-morph が上げられQ ‡ 管理面リポジトリでは既に jscodeshift の環境が整ってい たため、今回は jscodeshift を利用 ‡ https://github.com/facebook/jscodeshif‘
  10. ページの移行 url  ページの URL を示す isUnstated  後述 filePath

     移行後のファイルパス beforeDepth, afterDepth  移行前移行後のルートからの深さ componentPath  移行前のファイルパス
  11. 障壁② ~3世代に渡る状態管理ライブラリの混在~ WinTicket 管理面では3種類の状態管理ライブラリが混在している unstatef y Class Component 時代の状態管理ライブラn y

    一番の障壁 Recoiˆ y Hook ベースの状態管理ライブラリ TanStack Querq y 非同期状態の管理を得意とするライブラn y 最近 WINTICKET 本体は Redux から TanStack Query に移行した ( ) 参考 障壁
  12. 障壁② ~3世代に渡る状態管理ライブラリの混在~ その他 unstated /$campaignId ├─ index.tsx : ルーティング用のコンポーネント └─

    -CampaignDetail.tsx : ページの実態 ├─ -Injector.tsx : ロジックとステートを注入する層 /$campaignId ├─ index.tsx : ルーティング用のコンポーネント └─ -CampaignDetail.tsx : ページの実態
  13. 目次 01 WINTICKET について 02 TanStack Router への移行背景 03 ページの移行

    04 ルーティング処理の移行 05 移行してみて 06 おわりに
  14. ルーティング処理の移行 前提 A react-router v5 が提供する Route コンポーネントを利用していた A Route

    コンポーネントは対象に RouteComponentProps で定義された型を インジェクトすH A ※v6 では非推奨 A RouteComponentProps の中でも、history, location, match のみが利用されていx A history : History オブジェクト。主に history.push でのページ遷移に利€ A location : History API の location インターフェー— A match : パスパラメータを取得するために利用
  15. ルーティング処理の移行 方針 4D location, history, match それぞれ Props で 展開されている

    → コンポーネント内で Hook を利用 ™D match.params を useParams に書き換p g from には前述の route-info.json を利用 tD location.search を location.searchStr に 書き換え
  16. ルーティング処理の移行 方針 4D location, history, match それぞれ Props で 展開されている

    → コンポーネント内で Hook を利用 ™D match.params を useParams に書き換p g from には前述の route-info.json を利用 tD location.search を location.searchStr に 書き換え
  17. ルーティング処理の移行 方針 4D location, history, match それぞれ Props で 展開されている

    → コンポーネント内で Hook を利用 ™D match.params を useParams に書き換p g from には前述の route-info.json を利用 tD location.search を location.searchStr に 書き換え
  18. ルーティング処理の移行 方針 4D location, history, match それぞれ Props で 展開されている

    → コンポーネント内で Hook を利用 ™D match.params を useParams に書き換p g from には前述の route-info.json を利用 tD location.search を location.searchStr に 書き換え
  19. ルーティング処理の移行 方針 4D location, history, match それぞれ Props で 展開されている

    → コンポーネント内で Hook を利用 ™D match.params を useParams に書き換p g from には前述の route-info.json を利用 tD location.search を location.searchStr に 書き換え もちろんこれは既存実装が統一されている場合の話です 実際は AST の変換をしやすいように 事前にコードを整える必要がありました
  20. 障壁③ ~useHistory~ TanStack Router が useHistory Hook を提供していない 自前で実装する 障壁

    解決策 useHistory とはq p History オブジェクトにアクセスするための Hooku p React Router v6 でも廃止
  21. 障壁③ ~generatePath~ ex) generatePath("/users/:id", { id: "42" }); /users/42 generatePath("/files/:type/*",

    { type: "img", "*": "cat.jpg", }); /files/img/cat.jpg React Router が提供するパス解決用の関数 o https://reactrouter.com/en/main/utils/generate-path
  22. 障壁③ ~generatePath~ そもそも TanStack Router が generatePath を提供していない 課題 GitHub

    で React Router のソースを読み、自前で実装する 解決策
  23. 今後の展望 unstated の脱b B 現在チーム一丸で進行中 u B -Injector.tsx が存在する unstated

    が利用されているページを TanStack Query に移行u B -Injector.tsx が生えたことで、unstated に依存しているページの特定が楽に useHistory の脱b B useNavigate, useParams, useSearch 等の TanStack Router が提供する Hook に移行
  24. We are HIRING !!!  WINTICKET Web で働いてくれる人を募集していますF  圧倒的若手チーム(全員20代5

     Web っぽいことだけに閉じずに CI/CD やインフラ周りを触る機会もアリ