乐趣区

关于微前端:微前端-SingleSPA

什么是微前端?

微前端就是依据不同的性能拆分成多个独立模块(子利用), 通过主利用来加载这些子利用。微前端的外围在于拆,拆完后在合。

微前端的应用场景

  1. 不同团队开发同一个利用,然而用到的技术栈不同的状况下
  2. 每个团队独立开发部署,不依赖于别的团队代码
  3. 老的我的项目代码和新的技术栈在同一利用中交融

有人说了这用 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')
}
退出移动版