🧊

マイクロフロントエンドフレームワークicestarkが最高すぎる件

2022/06/26に公開

今お世話になっているスタートアップの会社さんで、フロントエンドのVue2アプリケーションをマイクロフロントエンド化しました。

今後、Vue.jsを取り巻く環境が急激に変わった場合を想定し、React.jsもしくはVue3にアップデートしていくために、マイクロフロントエンドアーキテクチャを採用しました。

圧倒的な速度で進化していくフロントエンドのツールおよびライブラリ、これら全てにキャッチアップをして、技術的負債を取り除いていくためには、すでにマイクロフロントエンド以外の選択肢を除いてないと思います。

今回紹介するicestarkを実際に使ってみた上で、より多くの人にこのicestarkを知ってほしい!と思ったので、まとめてみました。

ハンズオン記事はこちら:
https://zenn.dev/mikana0918/articles/24be5c00e2c2fc

更新履歴

Whyマイクロフロントエンド

今回はVue2.XからVue3.xのアップデートを漸進的に行うための決断でしたが、そもそもなぜマイクロフロントエンドなのでしょうか? メリットデメリットを検討してみました。

メリット

ありとあらゆる技術選定を柔軟にすることが可能です。

  • レポジトリを別にすることにより、必要なライブラリを限定し、バンドルサイズを削減。ビルド、デプロイを高速化できる
  • モジュールバンドラをレポジトリごとに変更できる
    => 例えば、従来通りwebpackを使うこともできるし、viteによるESMを使った高速バンドルも可能。
  • レポジトリごとに全く異なるフロントエンドのライブラリ(React.js/Vue.js/Svelteなど)を選定できる
  • レポジトリごとに全く異なるフロントエンドのフレームワーク(Next.js/Nuxt.jsなど)を選定できる
  • フロントエンドエンジニアのチームがスケールしたとしても、新しいマイクロフロントエンドを立てることで、チームも小さい単位で分割することができるようになる

今回はVue2からVue3へのアップデートが大きなペインで、マイクロフロントエンドへ投資してみましたが、結局のところきっかけがあれば意外とマイクロフロントエンド化はできてしまうんじゃないかなあと思います。

デメリット

初回の導入の難易度は非常に高く、工数もフルリプレイスまではいかなくとも、大規模アップデートを行う程度の工数は想定する必要があります。

  • マイクロフロントエンド化の工数
    • 10万行程度のVue2アプリケーションを2つのマイクロフロントエンドに分割する工数が240~300時間ほどでした。結構面倒...
  • マイクロフロントエンド化するためのリファクタリング箇所の多さ
    • マイクロフロントエンドにすることで、一部、画面遷移をブラウザのHisotry APIに準拠する必要がある
      一部で、vue-routerのrouter.push()が使えない
    • マイクロフロントエンドの状態とstandaloneで起動した状態2つでアプリケーションを起動可能にするには、ある程度の実装が必要

プロジェクトの規模にもよると思いますが、大規模なサービスだとやっぱりかなり面倒なマイグレーション作業になることは否めないと思います...

とはいえ、技術的な挑戦としてはやってよかったと思っています。採用にも効果があるといいなぁ...(遠い目)

icestarkとは

公式サイト: https://micro-frontends.ice.work/

icestark

https://icestark-react.surge.sh/
↑Angular/Vue/Reactで動作しているサンプルです

アーキテクチャコンセプト

詳細についてはgithubを参照: https://github.com/ice-lab/icestark

大きく分けて2種類のマイクロアプリケーションに分けられます。

  • メインアプリケーション
    フレームワーク共通のヘッダー、サイドバー、フッターなどレイアウトを担当するメインアプリケーション
  • サブアプリケーション
    react, vue, angularなど各種マイクロアプリケーション

特徴

  • 中国産のマイクロフロントエンドフレームワーク
  • taobao, Alimama.com, AliExpress, YOUKUなど大規模サービス採用事例
  • React, Vue, Angularなどフレームワークに縛られずマイクロフロントエンドが組める
  • url, entry, html content, iframeなど多様なマイクロアプリケーションの組み込み方を提供
  • パフォーマンス最適化のための機能shouldAssetsRemove, preloading, pre-execution, SSRに対応
  • webpackはもちろんviteに公式で対応(ES Module対応)
  • マイクロモジュール化対応
  • アプリケーション間通信対応
    @ice/stark-dataによるアプリケーション間の通信にも対応

結局、icestarkを使ったマイクロフロントエンドって何が嬉しいの?

マイクロフロントエンドを扱うために必要なモジュールが用意されているのが大きなメリットだと思います。

alibabaなど大規模なフロントエンド環境・チームで、実際に運用されている実績もあり、マイクロフロントエンドを作るのに必要な機能が全て揃っているのが素晴らしいです。

また、中国語ですがドキュメントも充実しており、まだまだアップデートも頻繁に行われていて、コミュニティの強さが伺えます。因みにですが、icestarkのメンテナはalibabaのエンジニアが多いようです。お金のある会社がバックにあるのは安心かなと。

例えば、micro app間でコンポーネントの再利用が必要になればマイクロモジュールの利用が検討できますし、アプリケーションを横断するstate管理については、@ice/stark-dataを使うことで、イベント駆動なデータの橋渡しを行うことができます。

最終的にできたローカル構成のサンプルなど

こんな感じのローカル構成になりました

認証について

僕たちのアプリケーションでは、認証(IDaaS)にauth0を使っていて、ローカルストレージにauth tokenを保存しています。

ローカルストレージはマイクロフロントとして起動する際に、全てのアプリケーションからlocalstorage API経由でtokenを取得できるため、親アプリケーションでauth0との認証を行い、子アプリケーションがicestarkのマイクロフロントエンドとして動作している場合については、localstorage経由でauth tokenを取得するようにします。

そのために、icestarkから提供されるisInIcestark()が使えます。

import { isInIcestark } from "@ice/stark-app/lib";

if(isInIcestark()) {
  // マイクロフロントエンドとして動いている場合
  // auth0認証を試す
  // ...
} else {
  // standaloneアプリケーションとして動いている場合
  // localstorageからauth tokenを取得
   localStorage.getItem("token");
}

オリジン間アクセスについて

httpsでローカルを動かしています。同じローカル証明書経由にして、異なるportからアクセスしています。

マイクロフロントエンドとして動かす際に、オリジン間のリソース共有があるので、viteに下記の設定を仕込んでいます。ローカルなので、Access-Control-Allow-Origin全て許可し、親アプリケーションと子アプリケーションの間でオリジン間アクセスを許可します。

      headers: {
        'Access-Control-Allow-Origin': '*'            
      },

standalone / microfrontendの子アプリケーションの切り替え

icestarkの中でアプリケーションが起動しているかをチェックします。

子アプリケーションにおいて、レイアウト部分については、マイクロフロントエンドとして起動する場合に、重複してしまうので。マイクロフロントエンドの場合は隠すようにしてしまいます。

<template>
    <MainHeader v-if="!withinMicrofrontendApp" />
    <v-main class="main-content" fluid>
      <div class="main-content__wrapper">
        <MainSidebar v-if="!withinMicrofrontendApp" />
        <div class="main-content__view">
          <router-view />
        </div>
      </div>
    </v-main>
</template>

<script lang="ts">
import { Vue, Component } from "vue-property-decorator";
import { isInIcestark } from "@ice/stark-app/lib";

@Component({})
class DefaultLayout extends Vue {
  get withinMicrofrontendApp() {
    return isInIcestark();
  }
}
</script>

scoped slotを使ったmicrofrontend判定コンポーネントを作ってもいいかもしれないですね。

実際にicestarkを使ってマイクロフロントエンド化してみた感想

  • ドキュメントが中国語なので、都度、Chromeなどの翻訳機能を使うのが面倒
    最近、英語ドキュメント作成の話がgithubにも出ていたので、近日解決されるかも?
  • Vue 2.X系のマイクロフロントエンド化のドキュメントが薄くて、自力でキャッチアップするのに苦労した

https://github.com/mikana0918/icestark-layout-sample
https://github.com/mikana0918/icestark-vue2-child-sample

解説記事はこちら
https://zenn.dev/mikana0918/articles/24be5c00e2c2fc

icestarkフレームワークライフサイクルの画像が上記なのですが、英語化されないと正直意味がわからないですよね...

ひとまず、真ん中の onActiveAppsなどライフサイクルフックについてはicestarkのオンラインドキュメントに記載があるので、そちらを参照するとよさそうです。

https://micro-frontends.ice.work/docs/api/ice-stark

デプロイについて

デプロイについては、いろいろな選択肢があると思いますが、弊社ではAWS Amplifyを使うことにしました。
他にはVercelNetlifyも候補にあがりそうです。

マイクロフロントエンドの場合、CORS対応が必要になるので、適切にリダイレクト、ヘッダーの変更が可能なクラウドプロバイダを選定する必要がありそうです。

もしくはS3 + CloudfrontなどのCDN構成もとてもマイクロフロントエンドと相性がよく、一考する価値はありそうです。

まとめ: icestarkは完成度の高いマイクロフロントエンドフレームワークです

かなりザッと流した紹介でしたが、icestarkは本番運用が可能なマイクロフロントエンドフレームワークです。

実際に導入する際の困りごとなどについては、別途記事化する予定ですが、マイクロフロントエンド化することでマージの競合も大幅に減ったような気がしますし、モジュール分割が進むことでアプリケーションの見通しも良くなる、さらにはVue.jsだろうがReact.jsだろうが好きなライブラリ選定ができる土台が整ったことで、フロントエンドの基盤がさらに強固になったと実感できています。

次にVue2からVue3ほど大きなアップデートが来たとしても、マイクロフロントエンドのルーティングを変えて、新しいレポジトリを立てるだけで漸進的にアップデートを進められるわけです。競合他社よりも圧倒的に素早く技術的負債を返済できていくので、事業への貢献もできるのかもしれません。

...いずれにしても、マイクロフロントエンド化することで、変化の早いフロントエンドの進化に耐えられるアーキテクチャを手に入れられるよ、という点が強調したいことで、icestarkのような有力な解決策もあるので、より多くの人に知ってほしいと思った次第でした。

一旦、以上となります。ここまで通読ありがとうございました!

Discussion