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

Nuxt 2から3へマイグレーションする方法考えてたら、マイクロフロントエンドのフレームワークができた話

Nuxt 2から3へマイグレーションする方法考えてたら、マイクロフロントエンドのフレームワークができた話

プロジェクトは Nuxt2 で、ページ数やコンポーネントの数、コードの絡み具合から、どうしても Nuxt Bridge を使ってのマイグレーションは困難と判断せざるを得なかった。 そこで、元の資産に手を加えずに、ページ単位で Nuxt3 にどうやって移行していくかを考えていくことにした。 試行錯誤の末、マイクロフロントエンドのフレームワークが生まれてしまったのでした。

株式会社hacomono
フロントエンドテックリード 基盤グループ Enabling チーム
VRChat フロントエンドエンジニア集会主催
みゅーとん / mew-ton

hacomono Inc.

October 31, 2023
Tweet

More Decks by hacomono Inc.

Other Decks in Technology

Transcript

  1. Nuxt2
    から 3
    へマイグレーションする方法考えてたら
    
    マイクロフロントエンドのフレームワークができた話

    View Slide

  2. 自己紹介
    みゅーとん
    趣味 .. VR,
    エレクトーン,
    アバターでの活動
    
    アバターワーク推進してます
    vue-fes 2022
    でもアバターで出てました
    採用面談で "
    アバターで来て"
    と依頼が・・
    "VRChat
    フロントエンドエンジニア集会"
    毎月開催してます






    X(twitter) .. @_mew_ton
    github .. mew_ton
    avatar .. ©
    まめひなた/
    もち山金魚

    View Slide

  3. 自己紹介 (
    中の人)
    所属:
    株式会社hacomono
    Platform Group / Enabling Team
    Frontend Tech Lead
    いろんなプロジェクト・チームを横断で面倒みます
    基盤のメンテもしてます
    
    今年になって、はじめて OSS
    公開しました
    






    X(twitter) .. @_mew_ton
    github .. mew_ton
    avatar .. ©
    まめひなた/
    もち山金魚

    View Slide

  4. 注意
    ※ 以下については説明を省略します
    
    所属 (hacomono)
    について
    ブースがあるので見てね
    
    マイクロフロントエンド is
    何?
    マイクロサービス,
    モジュラーモノリス
    ドメインの境界
    
    Nuxt Bridge
    を導入できない理由
    直接聞きに来てください







    View Slide

  5. あらすじ

    View Slide

  6. はじまり
    
    
    
    
    
    ※ 実際の出来事とは異なります。説明のために歴史の歪曲や誇張があります。

    View Slide

  7. はじまり
    弊社のフロントエンドのプロジェクトは
    合計4つある

    View Slide

  8. はじまり
    管理サイトとメンバーサイトがある
    今回は管理サイトのお話

    View Slide

  9. はじまり
    管理者向けアプリ (
    以後:
    管理サイト)

    多くのドメインを集約していった結果 ・・・
    
    Components .. 700 vue files, 100000 lines
    Pages .. 600 paths, 50000 lines
    Vuex Store .. 200 files, 700 stores
    

    クソデカモノリスフロントエンド
    

    View Slide

  10. はじまり
    mixin
    依存などのアンチパターンも多く踏んでいる
    Nuxt Bridge
    を導入できない仕組みにもなっている
    
    導入推進できる人員が私 1
    人しかいない
    私自身も横断でプロジェクトを面倒みるのでほぼ無理
    
    

    半ば諦めてた
    
    
    

    View Slide

  11. はじまり
    デザイナーチームから
    ページ階層構造を含む大きめのリデザインが提案される
    
    

    どうせ作り直すなら、リアーキテクチャを同時に走らせてくれ

    View Slide

  12. 要件
    Nuxt2 → Nuxt3
    移行を逐次的に行う
    Nuxt Bridge
    を導入できない
    Nuxt2
    側も継続してメンテを続ける
    フロントエンドの基盤まわりに手を入れられる人がほぼいない
    複雑なことを任せない
    
    
    
    ※ 走り切るための施策など様々ありますが、今回はスコープ外なので割愛





    View Slide

  13. Nuxt2 → Nuxt3

    View Slide

  14. 管理サイトのレイアウト

    View Slide

  15. 解決のアプローチ (1)
    Nuxt3
    で同じレイアウトを作る

    View Slide

  16. 解決のアプローチ (2)
    iframe
    だけのページを作る

    View Slide

  17. 解決のアプローチ (3)
    旧サイトのヘッダーとサイドバーを非表示にして、 iframe
    からこれを見に行く

    View Slide

  18. 解決のアプローチ (4)
    Nuxt3
    側に新しいページを実装していく
    Nuxt2
    側でアクセスしなくなったページへの遷移を Nuxt3
    の新しいページへのリダイレクトに変更


    View Slide

  19. おわり …?

    View Slide

  20. View Slide

  21. Q&A
    
    
    そもそも iframe
    使いたくない
    目を背けるな
    
    NuxtBridge
    が使えないなら、残りの選択肢は
    作り直し
    iframe
    諦める
    の3択だぞ・・!



    View Slide

  22. Q&A
    
    Cookie
    どうするの
    nuxt.config.ts
    で app.baseURL
    を /v2
    などの適当な値にする
    /v2
    へのアクセスが新しい方にルーティングするように nginx
    等で組めば良い
    
    パフォーマンスに影響でない?
    1
    ページに 1
    個 iframe
    を置くので、問題ない
    問題あるなら、それは旧サイト側が重い
    
    ページ遷移アニメーションは?
    そもそもしないんで・・

    View Slide

  23. Q&A
    
    iframe
    内側でページが変わった時、ブラウザのアドレスバーが更新されない
    ・・・・・
    
    iframe
    内側から、外側のページ遷移を呼び出すには?
    ・・・・・・・
    
    モーダルやドロワーの位置ずれない?
    ・・・・・・・・・・・・・・
    
    旧サイトを同期的にいじりたくない
    ・・・・・・・・・・・・・・・・・・

    View Slide

  24. 追加要件 1
    iframe
    で SPA
    を開きつつ、1
    つの SPA
    として見せかけるような仕組みにする
    ページ遷移を iframe
    間で同期
    e.g.
    外が #/bridge/user/3
    にアクセスしたら、 iframe
    内は #/user/3
    iframe
    内の modal
    などの位置調整の仕組み
    
    旧サイトの修正を頻繁にしない
    Nuxt3
    側に新ページができたときのルーティング先変更を Nuxt2
    側に実装しない
    
    
    (
    複雑になってきた・・)




    View Slide

  25. 解決のアプローチ v2
    可能な限りシンプルに解決する
    iframe
    の親と子間で Post Message
    を用いて必要な情報伝達をする
    

    View Slide

  26. 事前準備 1
    iframe
    用ページを可変長のパスにする

    View Slide

  27. 事前準備 2
    pageMeta
    の key
    に固定の文字列を設定
    /bridge/[…paths]
    の paths
    が変わっても再描画されなくする

    View Slide

  28. ルーティング更新のイメージ 1
    /bridge
    に続くパスと同じパスへアクセスする
    

    View Slide

  29. ルーティング更新のイメージ 2
    Nuxt3
    側にページを作ったら、
    存在するパスへリダイレクトする
    
    親側がルーティングを制御するため
    子側は修正不要
    

    View Slide

  30. ルーティングの同期 (1)
    ルート変更を検知
    子に変更情報を伝える

    
    
    
    
    

    受け取ったパスへ
    そのまま遷移する

    View Slide

  31. ルーティングの同期 (2)
    受け取ったパスから
    遷移すべきパスを算出し
    遷移する

    
    
    
    

    ルート変更を検知
    親へ変更情報を伝える
    

    View Slide

  32. モーダル等の位置調整
    iframe
    の位置やスタイルで調整すれば、目的の場所に表示させることはできる
    ずらすべき値は親側のみが知っている

    View Slide

  33. モーダルの位置調整
    DOM
    の変化トリガーで
    
    子に位置情報をおくる

    
    
    
    
    
    

    Vue
    の Reactive
    に
    
    落とし込む

    View Slide

  34. 💡

    View Slide

  35. 気づき
    メインの仕組みは Vue/Nuxt
    ではなく、 Post Message
    である
    
    要件の Nuxt3, Nuxt2
    に限定する必要性がそもそもない
    
    限定しなければ、マイクロフロントエンド化ができる

    View Slide

  36. 新構成のアイデア

    View Slide

  37. マイクロフロントエンド
    
    右の本で紹介されている
    垂直分割アーキテクチャの手法に同じ
    
    ページパスがマイクロフロントエンドを分割する
    
    マイクロフロントエンドの分割単位はドメイン毎であるべきだが
    管理サイトはページパスごとにゆるく別れてるのでOK

    View Slide

  38. 追加要件 2
    クソデカモノリスフロントエンドはもうやめたい
    Nuxt3
    でまた 700 Component, 600 Pages
    作るの?もう嫌だよ
    
    API
    のモジュラーモノリス化が並行して動いていたので丁度よい

    View Slide

  39. 解決のアプローチ v3
    マイクロフロントエンドにしてしまう
    post message
    部分を共通化し、 Vue
    に依存する部分を切り分けて実装できるように作り直す

    View Slide

  40. ロジックの分割
    コアロジックを汎用化できる, vue
    プラグインはそのラッパーでしかない
    

    View Slide

  41. 💡

    View Slide

  42. OSS

    View Slide

  43. @passerelle

    View Slide

  44. @passerelle
    
    命名: Chat-GPT 3
    passerelle ..
    人道橋,
    橋渡し (
    フランス語)
    
    親側 .. enclosure
    子側 .. insider
    




    View Slide

  45. ライブラリ化

    View Slide

  46. @passerelle
    フレームワーク
    
    iframe
    を使う垂直分割アーキテクチャでのマイクロフロントエンド フレームワーク
    コアロジックは post message
    部分のみ
    フロントエンドフレームワーク のプラグインとして導入
    現在 vue 2.7, 3 (vue-router 3.6, 4)
    のみサポート
    鋭意制作中 !
    vue -2.6 / nuxt 2 / nuxt 3
    サポート開発中
    ドキュメント作成中
    
    GitHub: 
    https://github.com/hacomono-lib/passerelle
    https://github.com/hacomono-lib/passerelle-vue
    ※ 重要:
    年収アップに直結してるので、ぜひスターください







    View Slide

  47. Pros / Cons
    Pros
    
    他の重厚な MFE
    フレームワークに比べて、実装がシンプル
    Router
    とのつなぎ込み部分だけでほぼ構成される
    フレームワークの選定自由度が上がる
    
    Cons
    
    iframe
    を利用するため デザイン周りがつらくなる
    Modal / Drawer
    などの positon absolute
    や z-index
    が絡むスタイル調整が特に面倒になる
    私がしんどい (react
    とか技術的にできそうだけど、やるのかな)






    View Slide

  48. まとめ
    Nuxt2 → Nuxt3
    に逐次的にアップデートしていく方法を考えた
    iframe
    を使ってちまちま作ってたら、マイクロフロントエンド化のアイデアができた
    せっかくなので OSS




    View Slide

  49. おわり

    View Slide

  50. おまけ
    ※ 本題からズレます

    View Slide

  51. マイクロフロントエンド化の
    
    別解

    View Slide

  52. Nuxt3
    のみで作る
    
    マイクロフロントエンド
    
    アーキテクチャ

    View Slide

  53. マイクロフロントエンド化する範囲
    赤枠で iframe
    を使わないアイデア

    View Slide

  54. Nuxt3
    だけで作る MFE:
    手順1
    pages
    配下が競合しないように複数のプロジェクトを作る
    結合用の Nuxt3
    プロジェクトを 1
    個作る


    View Slide

  55. Nuxt3
    だけで作る MFE:
    手順2
    結合用 Nuxt3
    プロジェクトの Nuxt Config
    で extends
    を設定する
    結合用 Nuxt3
    プロジェクトを Build
    する
    複数のプロジェクトが結合されてビルドされる!!!!



    View Slide

  56. 完成!

    View Slide

  57. Pros / Cons
    Pros
    
    最もシンプル
    モノレポにすると便利
    
    Cons
    
    Nuxt3
    以外の選択肢が失われる
    1から作るケースには向かなさそう (
    根拠なし)
    Component
    や Page
    のパスなどが 名前衝突で上書きされる
    ビルドタイム結合なので デプロイタイミングが制限される
    

    モジュラーモノリスフロントエンド・・としてはアリ・・?






    View Slide

  58. おわり

    View Slide