2021-04-26 single-spa-vue 微前端初实践

SingleSpa - VueCli - 微前端落地方案

  1. 创建项目parent-vue和child-vue两个项目
  2. vue create parent-vue
  3. vue create child-vue
parent-Vue
  1. 安装依赖: yarn add

  2. yarn add single-spa

  3. main.js改造

    import Vue from "vue";
    import App from "./App.vue";
    import router from "./router";
    import store from "./store";
    
    Vue.config.productionTip = false;
    
    import './single-spa';
    
    new Vue({
      router,
      store,
      render: (h) => h(App),
    }).$mount("#app");
    
    // single-spa.js
    import { registerApplication, start } from "single-spa";
    
    async function loadScript(url) {
      return new Promise((resolve, reject) => {
        // 创建标签,并将标签加到head中
        let script = document.createElement("script");
        script.src = url;
        script.onload = resolve;
        script.onerror = reject;
        document.head.appendChild(script);
      });
    }
    // 注册应用
    registerApplication(
      "myVueApp",
      async () => {
        // 加载子组件导出的类库和资源,注意先后顺序
        await loadScript(`http://localhost:3001/js/chunk-vendors.js`);
        await loadScript(`http://localhost:3001/js/app.js`);
        return window.singleVue; // 返回子应用里导出的生命周期,mount,ummount,bootstrap
      },
      // 当用户切换到/myVueApp的路径下时,加载刚才定义子子应用
      (location) => location.pathname.startsWith("/myVueApp")
    );
    start();
    

child-Vue

  1. 安装依赖: yarn add single-spa-vue

  2. vue.config.js调整

    module.exports = {
      publicPath: "//localhost:3001/",
      // css在所有环境下,都不单独打包为文件。这样是为了保证最小引入(只引入js)
      css: {
          extract: false
      },
      // chainWebpack: config => {
      //   config.externals(['vue', 'vue-router']);
      // },
      configureWebpack: {
        output: {
          library: "singleVue",
          //挂载目标 umd or window
          libraryTarget: "umd",
        },
        devServer: {
          contentBase: './',
          compress: true,
          port: 3001,
        },
      },
    };
    
  3. main.js改造

    import Vue from "vue";
    import App from "./App.vue";
    import router from "./router";
    import store from "./store";
    
    import singleSpaVue from 'single-spa-vue';
    
    Vue.config.productionTip = false;
    
    const appOptions = {
      el: '#child-vue', // 挂载到父应用中id为vue的标签中
      router,
      store,
      render: h => h(App)
    }
    
    // 使用 singleSpaVue 包装 Vue,
    // 包装后返回的对象中vue包装好的三个生命周期,bootstrap,mount,unmount,
    const vueLifeCycle = singleSpaVue({ Vue, appOptions });
    
    // 协议接入,我们定好了协议,父应用会调用这些方法
    export const bootstrap = vueLifeCycle.bootstrap;
    export const mount = vueLifeCycle.mount;
    export const unmount = vueLifeCycle.unmount;
    
    /*
    new Vue({
      router,
      store,
      render: (h) => h(App),
    }).$mount("#app");
    */
    

参考

  1. https://www.yuque.com/xwifrr/zqg2pw/xganz7
  2. https://blog.csdn.net/weixin_39085822/article/details/108832278

你可能感兴趣的:(2021-04-26 single-spa-vue 微前端初实践)