We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
我わが们团队正在ざい做一个XX系けい统,技わざ术栈是ぜReact,目前もくぜん该系统日渐庞大だい,开发及维护成本ほん加か大だい,且每次じ必须把わ整せい个项目め一いち起おこり打だ包つつめ,费时费力。经考虑后决定将はた其拆分ぶん成なり多た个项目め,由ゆかり它们组合成ごうせい一个完整系统,微ほろ前端ぜんたん架か构是非常ひじょう好このみ的てき选择。
React
微ほろ前端ぜんたん差さ不ふ多た有ゆう以下いか几个好こう处:
商品しょうひん模も块
对我们来说最大さいだい的てき好こう处是单项目め维护。
单项目め维护
我わが们将整せい个微前ぜん端はし分ぶん为两个部分ぶん:
注意ちゅうい看み地ち址し栏变化か,其中包含ほうがん /app1/xxx和わ/app2/xxx,乍一看这是一个项目中两个页面的切换,实际上じょう是ぜ来き自じ两个独立どくりつ的てき项目,app1 和わ app2 来らい自じ不同ふどう的てき git 仓库。
/app1/xxx
/app2/xxx
整せい个流程ほど大概たいがい为:用よう户访问 index.html, 此时运行模も块加载器Js,加か载器会かい根ね据すえ整せい个系统的配置はいち文ぶん件けん(project.config) 去さ注ちゅう册さつ各かく个项目め,系けい统会先さき加か载主项目(Main),然しか后きさき会かい根ね据すえ路ろ由ゆかり前ぜん缀动态加载对应的子こ项目
我わが们这个架构也参考さんこう了りょう网上很多好このみ的てき文章ぶんしょう,其中核心かくしん文章ぶんしょう可か参考さんこう https://alili.tech/archive/11052bf4/
大概たいがい如下
[ { 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。
我わが们技术栈是ぜ 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 这里有ゆう很多例れい子こ
我わが们使用しよう的てき 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 来らい动态加か载模块入口こう。
关于这个也看了りょう一些大佬的方案,大概たいがい就是所有しょゆう的てき项目里さと有ゆう个 store,在ざい注ちゅう册さつ入口いりくち时将所有しょゆう store 放ひ进队列れつ,需要じゅよう更新こうしん store 里さと的てき状じょう态时,调用 dispatch 将しょう所有しょゆう store 同どう步ふ。
我が的てき做法和わ传统单页应用一いち样,一个系统应该只有一个顶级 Store,由ゆかり于顶级 Store 里さと存そん的てき一般是整个系统的公用状态 比ひ如菜单、用よう户信息いき等とう,我が把わ它放在ざい Main项目里さと,但ただし打だ包つつみ时这个Store是ぜ单独抽离的てき:
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 就可以,非常ひじょう方便ほうべん。 注意ちゅうい:我わが使用しよう的てき是ぜ Mobx 作さく为状态管理かんり
我わが们部署しょ的てき方式ほうしき非常ひじょう简单,我わが自己じこ写うつし了りょう一いち个 webpack 插件用よう于把打だ包つつみ后きさき的てき dist 传到 OSS 然しか后きさき将はた项目信しん息いき传给服ふく务端,服ふく务端根ね据すえ我わが传入的てき项目信しん息いき组织成なり project.config,然しか后きさき用よう户在访问 index.html 时会获取 project.config,此时 single-spa 根ね据すえ配置はいち注ちゅう册さつ所有しょゆう项目,然しか后きさき根ね据すえ路ろ由来ゆらい拉ひしげ取ど对应的てき项目入口いりくち文ぶん件けんjs文ぶん件けん。
我わが们的需求是ぜ 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地ち址し:https://github.com/Vibing/micro-frontend
这是我わが们第一いち次じ玩微前ぜん端はし,可能かのう有ゆう很多地方ちほう不ふ完かん美び,还望各位かくい大だい佬多多た包つつみ涵
The text was updated successfully, but these errors were encountered:
No branches or pull requests
React
,商品 模 块
单拉对我们来说最大 的 好 处是
单项目 维护
。UI示 例 图
动图展示
/app1/xxx
/app2/xxx
,乍一看这是一个项目中两个页面的切换,实际关于 project.config
single-spa
如果你使用 vue,可 以使用 single-spa-vue
Webpack与 SystemJs
为了方便 项目动态加 载,我 们也参考 网上大 佬的想 法 ,使用 了 systemjs,只 不 过我们使用 的 是 0.20.19 版本 ,配合 systemjs ,在 Webpack 中 需要 改 一 下 libraryTarget:
app之 间通信
关于这个也看了 一些大佬的方案,大概 就是所有 的 项目里 有 个 store,在 注 册 入口 时将所有 store 放 进队列 ,需要 更新 store 里 的 状 态时,调用 dispatch 将 所有 store 同 步 。
这样就可以达到只 管理 这一个 Store 就可以,非常 方便 。
注意 :我 使用 的 是 Mobx 作 为状态管理
demo
demo地 址 :https://github.com/Vibing/micro-frontend
结束语
这是我 们第一 次 玩微前 端 ,可能 有 很多地方 不 完 美 ,还望各位 大 佬多多 包 涵
The text was updated successfully, but these errors were encountered: