しおしお

IntelliJ IDEAのことなんかを書いてます

single-spaでマイクロフロントエンドしてみる

single-spa | single-spaなるマイクロフロントエンドさくっと作れそうなフレームワークを試してみました。

準備

single-spa はプロジェクト作成用などのcliを用意してくれているようなので、まずはそれをインストールします。

npm install --global create-single-spa

こんな感じにバージョン確認できればインストールは成功です。

create-single-spa --version
2.1.1

アプリケーションの作成手順

ここから新規で、single-spaを使ったマイクロフロントエンドなアプリケーションを作る流れになります。

ルートHTMLを持つプロジェクトの作成

create-single-spaコマンドを使って、moduleTyperoot-configを指定することでルートHTMLを持つプロジェクトを作成できます。 いくつか作成するプロジェクトに関する質問をされますが、好きなものを選ぶな&入力する感じでOKです。

create-single-spa --dir root-config --moduleType root-config

プロジェクトが作成できたら、早速起動してみましょう。

cd root-config
npm run start

ブラウザで、http://localhost:9000にアクセスしてこんな感じのページが表示されればOKですね! f:id:sioiri:20210228063528p:plain

1つめのマイクロフロントエンドとなるアプリケーションの作成

マイクルフロントエンドとなるアプリケーションも、create-single-spaを使って作成できます。 frameworkには、色々なもの*1が指定できますが、今回はvueを指定して2系でプロジェクトを作ってみます。 vueを指定した場合、vue-cliが実行されプロジェクトが作成されます。

create-single-spa --dir vue2-app --framework vue

さっそくプロジェクトを起動してみましょう。

cd vue2-app
npm run serve

ブラウザでhttp://localhost:8080にアクセスすると、いつものVueなアプリケーションの画面が表示されませんね… これは、run serveで起動した場合、結合モードでマイクロフロントエンド側のアプリケーションとして実行されていて単体での画面表示ができないことが原因みたいですね。 f:id:sioiri:20210228064605p:plain

マイクロフロントエンド側のアプリケーション単体で画面表示&開発をしたい場合にはserve:standaloneで起動してあげます。

npm run serve:standalone

これで再度ブラウザで表示してみるといつもの見慣れた初期画面が表示されますね。 f:id:sioiri:20210228065025p:plain

vue2のアプリケーションであることがさくっとわかるように、src/App.vueのtemplateを書き換えておきます。

<template>
  <div id="app">
    <h1>vue2 app</h1>
    <router-view/>
  </div>
</template>

ポートかぶりをなくすために、vue.config.jsを作成して、使用するポートも変更しておきます。

module.exports = {
    devServer: {
        port: 9001,
        disableHostCheck: true
    }
}

2つめのマイクロフロントエンドとなるアプリケーションの作成

1つ目と同じようにcreate-single-spaを使って作成していきます。2つ目のサービスはVueの3系を指定して作ってみます。

create-single-spa --dir vue3-app --framework vue

以降の手順は、1つ目のプロジェクトと同じため省略します。ポートは連番でわかりやすく9002に変更しておきます。

作成した2つのサービスを使って画面表示してみる

最初に作った、root-config側を編集して、2つのマイクロサービスを切り替えて画面表示していきます。

cd root-config
vi src/index.ejs

@single-spa/welcomeが記述されている行を探し、importmapを変更していきます。 importmapの名前には、各マイクロフロントエンドサービスのpackage.jsonに指定されている名前を指定するのがわかりやすいでしょう。 JavaScriptのパスは、マイクロフロントエンドサービスをnpm run serveで起動した際に画面に表示されているパス(下の画像の赤枠のパス)を指定します。 f:id:sioiri:20210228070846p:plain

  • 変更前
  <% if (isLocal) { %>
  <script type="systemjs-importmap">
    {
      "imports": {
        "@single-spa/welcome": "https://unpkg.com/single-spa-welcome/dist/single-spa-welcome.js",
        "@siosio/root-config": "//localhost:9000/siosio-root-config.js"
      }
    }
  </script>
  <% } %>
  • 変更後
  <% if (isLocal) { %>
  <script type="systemjs-importmap">
    {
      "imports": {
        "@siosio/root-config": "//localhost:9000/siosio-root-config.js",
        "@siosio/vue2-app": "http://localhost:9001/js/app.js",
        "@siosio/vue3-app": "http://localhost:9002/js/app.js"
      }
    }
  </script>
  <% } %>

続いて、各マイクロフロントエンドサービスの画面を表示する部分を変更しています。 変更する部分は、route defaultが記述されているあたりになります。 routepathを指定することでパスによって表示するマイクロフロントエンドサービスを切り替えられるようです。 applicationnameには、上で編集したimportmapの名前を指定してあげます。

  • 変更前
      <main>
        <route default>
          <application name="@single-spa/welcome"></application>
        </route>
      </main>
  • 変更後
      <main>
        <route path="/vue2">
          <application name="@siosio/vue2-app"></application>
        </route>
        <route path="/vue3">
          <application name="@siosio/vue3-app"></application>
        </route>
      </main>

アプリケーションを起動して画面表示をしてみましょう。

npm run start

ブラウザで、http://localhost:9000/vue2/http://localhost:9000/vue3で、それぞれのマイクロフロントエンドサービス側の画面が表示されれば成功ですね。

おわり。