微前端
- 微前端如何解决业务场景的痛点,并以qiankun为例
- 微前端的核心实现原理,并手把手实现简单微前端
背景
微前端最早于2016年在Micro-Frontends被提出,并建⽴了早期的微前端模型。微前端的命名和能 ⼒和微服务有类似之处,微服务与微前端,都是希望将某个单⼀的单体应⽤,转化为多个可以独⽴运 ⾏、独⽴开发、独⽴部署、独⽴维护的服务或者应⽤的聚合,从⽽满⾜业务快速变化及分布式多团队并 ⾏开发的需求。如康威定律(Conway’s Law)所⾔,设计系统的组织,其产⽣的设计和架构等价于组织间 的沟通结构;微服务与微前端不仅仅是技术架构的变化,还包含了组织⽅式、沟通⽅式的变化。微服务 课程⼤纲 2 与微前端原理和软件⼯程,⾯向对象设计中的原理同样相通,都是遵循单⼀职责(Single Responsibility)、关注分离(Separation of Concerns)、模块化(Modularity)与分⽽治之(Divide & Conquer)等基本的原则。
什么是微前端
一种类似于微服务的架构,是一种由独立交付的多个前端应用组成整体的架构风格,将前端应用分解一些更小、更简单的能够独立开发、测试、部署的应用,而在用户看来仍然是内聚的单个产品
现代web应用面临的问题
DX(developer experience)
- 多个系统在一个仓库应用中,不同子应用独立SPA模式
- 系统分为多个仓库,独立上线部署,采用MPA模式(公司采用这种)
UX(user experience)
- 性能体验
- 页面跳转和用户体验问题
微前端的意义
微前端的主要特点:
- 低耦合:当下前端领域,单⻚⾯应⽤(SPA)是⾮常流⾏的项⽬形态之⼀,⽽随着时间的推移以及 应⽤功能的丰富,单⻚应⽤变得不再单⼀⽽是越来越庞⼤也越来越难以维护,往往是改⼀处⽽动全 身,由此带来的发版成本也越来越⾼。微前端的意义就是将这些庞⼤应⽤进⾏拆分,并随之解耦, 每个部分可以单独进⾏维护和部署,提升效率。
- 不限技术栈:在不少的业务中,或多或少会存在⼀些历史项⽬,这些项⽬⼤多以采⽤⽼框架类似 (Backbone.js,Angular.js 1)的B端管理系统为主,介于⽇常运营,这些系统需要结合到新框架 中来使⽤还不能抛弃,对此我们也没有理由浪费时间和精⼒重写旧的逻辑。⽽微前端可以将这些系 统进⾏整合,在基本不修改来逻辑的同时来同时兼容新⽼两套系统并⾏运⾏。
微前端的价值
常用的微前端方案
- qiankun, icestark 自己实现 JS 以及样式隔离
- emp Webpack5 Module Federation (联邦模块)方案
- iframe、WebComponent 等方案
基于qiankun的微前端整合
主应用(vue)
- main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import { registerMicroApps, start } from 'qiankun';
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount('#app')
// 加载微应用
registerMicroApps([{
name: 'vue app',
entry: '//localhost:8080/',
container: '#container',
activeRule: '/app1',
props: {
slogan: 'Hello Qiankun',
},
}]);
start();
微应用 (vue)
- public-path.js
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
- main.js
import './public-path';
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
let instance = null;
function render(props = {}) {
const { container } = props;
instance = new Vue({
render: (h) => h(App),
}).$mount(container ? container.querySelector('#app') : '#app');
}
// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
export async function bootstrap(props) {
// common.setCommonData(props)
console.log('bootstrap', props)
}
export async function mount(props) {
// common.initGlState(props)
console.log('mount', props)
render(props);
}
export async function unmount() {
instance.$destroy();
instance.$el.innerHTML = '';
instance = null;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。