什么是微前端?
微前端就是依据不同的性能拆分成多个独立模块(子利用), 通过主利用来加载这些子利用。微前端的外围在于拆,拆完后在合。
微前端的应用场景
- 不同团队开发同一个利用,然而用到的技术栈不同的状况下
- 每个团队独立开发部署,不依赖于别的团队代码
- 老的我的项目代码和新的技术栈在同一利用中交融
有人说了这用 iframe 一样能解决啊,留神,和微前端相比,iframe 有多个弊病。比方
1. 左侧是一个菜单,右侧内容是加载不同的 iframe,每当点击一个菜单就会加载整个模块的 js, 这重大影响了性能。
2. 当用户在某一个页面刷新浏览器时用户以后点开的会失落
SingleSpa 实战
1. 创立子利用
这里我创立一个 vue 子利用(react 没学过,当前有机会再整合)
vue create app1
2. 下载 single-spa-vue 包
npm install single-spa-vue
3. 创立主利用
vue create main-app
npm i single-spa
4. 主利用中的 main
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
// 动静增加 script 脚本
const loadScript = async (url)=> {await new Promise((resolve,reject)=>{const script = document.createElement('script');
script.src = url;
script.onload = resolve;
script.onerror = reject;
document.head.appendChild(script)
});
}
import {registerApplication, start} from 'single-spa';
// 注册子利用
registerApplication(
'app1',
async ()=>{
// 子利用对应的接口
await loadScript('http://localhost:10000/js/chunk-vendors.js');
await loadScript('http://localhost:10000/js/app.js');
return window.app1
},
// 当匹配 url 门路为 /app1 时
location => location.pathname.startsWith('/app1')
)
// 启动利用
start();
new Vue({
router,
render: h => h(App)
}).$mount('#app')
5. 主利用的 App.vue
<template>
<div id="app">
<el-container>
<el-aside width="200px">
<el-menu router class="el-menu-vertical-demo">
<el-menu-item-group>
<el-menu-item index="/app1"> 选项 1 </el-menu-item>
</el-menu-item-group>
</el-menu>
</el-aside>
<el-main>
<div id="app1"></div>
</el-main>
</el-container>
</div>
</template>
6. 子利用 main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import singleSpaVue from 'single-spa-vue'
Vue.config.productionTip = false
const appOptions = {
el: '#app1',// 要挂载到主利用的哪个元素上
router,
render: h => h(App)
}
// 返回一个生命周期对象
const vueLifeCycle = singleSpaVue({
Vue,
appOptions
});
// 子利用必须导出 以下生命周期 bootstrap、mount、unmount
export const bootstrap = vueLifeCycle.bootstrap;
export const mount = vueLifeCycle.mount;
export const unmount = vueLifeCycle.unmount;
export default vueLifeCycle;
7. 打包成供主利用应用的类库(子利用中的配置)
在 src 中增加 vue.config.js
module.exports = {
configureWebpack: {
output: {
library: 'app1',
libraryTarget: 'umd'// 挂载到 Windows 上
},
devServer: {port: 10000}
}
}
8. 设置子路由的配置
通过下面七个步骤的配置 能够显示出上面这样的页面,然而当点击 Home 这个路由时,他是默认跟着主利用跳转的,这里须要咱们配置一下子利用的路由门路是绝对于子路由的
子路由 router.js
const router = new VueRouter({
mode: 'history',
base: '/app1',// 主利用默认跳转 /app1 加载子路由 由此以 /app1 作为相对路径
routes
})
9. 设置子利用的 __webpack_public_path__
点击 About 加载 about.js 时申请的仍然是主利用门路下的 about.js,然而主利用中不存在,所以才会报上面的错,咱们须要给子利用指定一个__webpack_public_path__,在进行点击的时候默认将__webpack_public_path__指向子利用,间接在子利用下寻找该文件
在子利用中增加
if(window.singleSpaNavigate){__webpack_public_path__ = 'http://localhost:10000/'}
10. 子利用单个工程启动
这里须要判断一下是否为主利用所利用 如果没有 那么须要挂载到子利用的 id 上
if (!window.singleSpaNavigate){
delete appOptions.el;
new Vue(appOptions).$mount('#app')
}