マイクロフロントエンド(singleSpa+React)試遊
5560 ワード
前言
私达のチームは1つのXXシステムをして、技术のスタックは
React
で、今このシステムは日に日に膨大で、开発とメンテナンスのコストは増大して、しかも毎回プロジェクト全体を一绪に梱包しなければならなくて、时间と労力がかかります.考慮した結果,複数のプロジェクトに分割し,それらを組み合わせて完全なシステムにすることを決定し,マイクロフロントエンドアーキテクチャは非常に良い選択である.マイクロフロントエンドの差は多くありません.以下のメリットがあります.
単一プロジェクトを引き出して1つのプロジェクトを形成し、それは1つのグループによって単独でメンテナンスすることができ、良好なデカップリング
です.ディスプレイ
UIサンプル
マイクロフロントエンド全体を2つの部分に分けます.
動図展示
/app1/xxx
と/app2/xxx
を含むアドレスバーの変化に注意してください.一見、これは1つのプロジェクトの2つのページの切り替えであり、実際には2つの独立したプロジェクトから来ており、app 1とapp 2は異なるgit倉庫から来ています.マイクロフロントエンドアーキテクチャ図
全体のプロセスは、ユーザーがindexにアクセスすることです.htmlは、モジュールローダJsを実行します.ローダはシステム全体のプロファイル(project.config)に基づいて各プロジェクトを登録します.システムはまずメインプロジェクト(Main)をロードし、それからルーティング接頭辞に基づいて対応するサブプロジェクトを動的にロードします.
私たちのこのアーキテクチャもネット上の多くの良い文章を参考にして、その中の核心の文章は参考にすることができますhttps://alili.tech/archive/11...
プロジェクトについてconfig
だいたい次のようです
[
{
isBase: false,
name: 'app1',
version: '1.0.0',
//
hashPrefix: '/app1',
//
entry: 'http://www.xxxx.com/app1/dist/singleSpaEntry.js',
// Store
store: 'http://www.xxxx.com/main/dist/store.js'
}
......
]
テクノロジーの詳細
single-spa
マイクロフロントエンドを実現する倉庫を探して、比較してsingle-spaを使うことにしました.
我々のテクノロジースタックはreactであり、サブプロジェクトのエントリでsingle-spa-reactを使用して構築する必要があります.キーコードは以下の通りです.
import singleSpaReact from 'single-spa-react';
const reactLifecycles = singleSpaReact({
React,
ReactDOM,
rootComponent: Root,
domElementGetter
});
export function bootstrap(props) {
return reactLifecycles.bootstrap(props);
}
export function mount(props) {
return reactLifecycles.mount(props);
}
export function unmount(props) {
return reactLifecycles.unmount(props);
}
vueを使用する場合はsingle-spa-vueを使用できます
次に、システム・エントリ・ファイルにすべてのアイテムを登録します.
import * as singleSpa from 'single-spa';
singleSpa.registerApplication(
'app1',
() => SystemJS.import('app1-entry.js'),
() => location.hash.startsWith(`#/app1`),
props
);
詳細はsingle-spa公式サイトを参照してくださいhttps://single-spa.js.orgここには多くの例がある.
WebpackとSystemJs
私たちが使用しているlernaは、すべてのプロジェクトの依存パッケージを統一的に管理し、すべての依存パッケージのバージョンを統一することで、メンテナンスが非常に便利です.
Webpackのdll機能を使用して、react、react-dom、react-router、mobxなど、すべてのプロジェクトの共通依存パッケージを抽出します.
プロジェクトのダイナミックロードを容易にするために、私たちもネット上の大物の考えを参考にして、systemjsを使用しましたが、私たちは0.20.19バージョンを使用しています.systemjsに合わせて、WebpackでlibraryTargetを変更する必要があります.
output: {
publicPath: 'http://www.xxxxx.com/',
filename: '[name].js',
chunkFilename: '[name].[chunkhash:8].js',
path: path.resolve(__dirname, 'release'),
libraryTarget: 'amd', // amd
library: 'app1'
},
私たちはumd仕様を使用していないし、systemjsのImport Maps機能も使用していないし、直接projectを通過しています.configは、モジュールエントリを動的にロードします.
app間通信
これについてもいくつかの大物の案を見て、たぶんすべてのプロジェクトにstoreがあり、登録入口ですべてのstoreをキューに入れ、storeの状態を更新する必要がある場合、dispatchを呼び出してすべてのstoreを同期します.
私のやり方は伝統的な1ページの応用と同じで、1つのシステムは1つのトップストレージしかないはずです.トップストレージに保存されているのは一般的にシステム全体の共通状態、例えばメニュー、ユーザー情報などです.私はそれをMainプロジェクトに入れましたが、パッケージするとき、このストレージは単独で抽出されました.
entry: {
singleSpaEntry: './src/singleSpaEntry.js',
store: './src/store' //
},
このStoreは、登録時に各アイテムに転送されます.
// Store
const mainStore = await SystemJS.import(storeURL);
singleSpa.registerApplication(
'app1',
() => SystemJS.import('http://www.x.com/app1/entry.js'),
hashPrefix('/app1'),
{ mainStore }
);
singleSpa.registerApplication(
'app2',
() => SystemJS.import('http://www.x.com/app2/entry.js'),
hashPrefix('/app1'),
{ mainStore }
);
これにより、このStoreを1つだけ管理することができ、非常に便利です.注意:ステータス管理としてMobxを使用しています
フロントエンドの導入
私たちの配置方法は非常に簡単で、私は自分でwebpackプラグインを書いて、パッケージされたdistをOSSに伝えてからプロジェクト情報をサービス側に伝えて、サービス側は私が伝えたプロジェクト情報に基づいてprojectに組織しました.config、ユーザーはindexにアクセスします.htmlでプロジェクトが取得されます.configでは、single-spaが構成に基づいてすべてのアイテムを登録し、ルーティングに基づいて対応するアイテムエントリファイルjsファイルを引き出します.
サブプロジェクトのマウントDOMをMainプロジェクトに入れる
私たちのニーズはMainがプロジェクト全体のLayoutとして、その中性子プロジェクトのマウントDomもMainプロジェクトにあります.これはMainプロジェクトが完全にレンダリングされてから、サブプロジェクトをマウントする必要があります.私はネット上のいくつかのマイクロフロントエンドの実現を参考にして、domElementGetterの方法を参考にしました.
function domElementGetter() {
let el = document.getElementById('sub-module-wrap');
if (!el) {
el = document.createElement('div');
el.id = 'sub-module-wrap';
}
let timer = null;
timer = setInterval(() => {
if (document.querySelector('#content-wrap')) {
document.querySelector('#content-wrap').appendChild(el);
clearInterval(timer);
}
}, 100);
return el;
}
demo
demoアドレス:https://github.com/Vibing/mic...
終わりの言葉
これは私たちが初めてマイクロフロントエンドを游ぶので、完璧ではないところがたくさんあるかもしれませんが、皆さん、どうぞお許しください.