Vue搭建微前端

最近公司来了个项目,运行起来后,控制台报错,说是找不到“XXXXX”模块,让检查拼写错误之类的。

很郁闷,仔细检查项目,发现在main.js文件中引入了一个新的组件,之前没见过,

import singleSpaVue from 'single-spa-vue'

网上一搜,原来是前端微服务的一种技术,好吧,前端也要开启微服务时代了,真的是越来越后端化了。

接下来,微前端搭建摸索正式开启:

首先放上官网文档地址配置文件生成说明

 

一、涉及技术及框架

single-spa:连接主项目与子应用的桥梁
systemjs:浏览器端异步加载模块
single-spa-vue:vue子应用连接主应用插件

二、主应用工程搭建

1、vue-cli搭建vue项目

vue create root-web

2、改造root项目使用systemjs加载子应用,以下是index.html的改造

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Coexisting Vue Microfrontends</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="importmap-type" content="systemjs-importmap">
    <script type="systemjs-importmap">
      {
        "imports": {
          "navbar": "http://localhost:8080/js/app.js",
          "app1": "http://localhost:8081/js/app.js",
          "app2": "http://localhost:8082/js/app.js",
          "pms-transformation-operation-ui": "http://localhost:9091/js/app.js",
          "single-spa": "https://cdnjs.cloudflare.com/ajax/libs/single-spa/4.3.7/system/single-spa.min.js",
          "vue": "https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js",
          "vue-router": "https://cdn.jsdelivr.net/npm/vue-router@3.0.7/dist/vue-router.min.js"
        }
      }
    </script>
    <link rel="preload" href="https://cdnjs.cloudflare.com/ajax/libs/single-spa/4.3.7/system/single-spa.min.js" as="script" crossorigin="anonymous" />
    <link rel="preload" href="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js" as="script" crossorigin="anonymous" />
    <script src="https://unpkg.com/import-map-overrides@1.7.2/dist/import-map-overrides.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.1.1/system.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.1.1/extras/amd.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.1.1/extras/named-exports.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.1.1/extras/named-register.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.1.1/extras/use-default.min.js"></script>
  </head>
  <body>
    <script>
      (function() {
        Promise.all([System.import('single-spa'), System.import('vue'), System.import('vue-router')]).then(function (modules) {
          var singleSpa = modules[0];
          var Vue = modules[1];
          var VueRouter = modules[2];

          Vue.use(VueRouter)

          singleSpa.registerApplication(
            'navbar',
            () => System.import('navbar'),
            location => true
          );

          singleSpa.registerApplication(
             'pms-transformation-operation-ui',
             () => System.import('pms-transformation-operation-ui'),
             location => location.pathname.startsWith('/pms-transformation-operation-ui')
          );

          singleSpa.registerApplication(
            'app1',
            () => System.import('app1'),
            location => location.pathname.startsWith('/app1')
          )

          singleSpa.registerApplication(
            'app2',
            () => System.import('app2'),
            location => location.pathname.startsWith('/app2')
          )

          singleSpa.start();
        })
      })()
    </script>
    <!-- See https://github.com/joeldenning/import-map-overrides#user-interface  -->
    <import-map-overrides-full show-when-local-storage="overrides-ui"></import-map-overrides-full>
  </body>
</html>

使用system加载模块。singleSpa.registerApplication注册子应用,当路由匹配app1时会到远程加载子应用的代码。主应用加载公共资源vue、vue-router后子应用可以不打包这些。实现共享。

三、子应用改造

  1. 同样适用vue-cli创建项目
vue create spa-a
npm install single-spa-vue --save
npm install systemjs-webpack-interop --save //用于实现异步路由时主应用可加载代码分割块

2、改造main.js

import './set-public-path'
import Vue from 'vue';
import App from './App.vue';
import router from './routers/router';
import singleSpaVue from 'single-spa-vue';
import VueRouter from 'vue-router'
Vue.config.productionTip = false;
Vue.use(VueRouter)
const vueLifecycles = singleSpaVue({
  Vue,
  appOptions: {
    render: (h) => h(App),
    router
  },
});

export const bootstrap = vueLifecycles.bootstrap;
export const mount = vueLifecycles.mount;
export const unmount = vueLifecycles.unmount;

暴露3个方法bootstrap 、mount 、unmount 使主应用和子应用实现通信

set-public-path主要用于子应用适用异步路由时主应用能加载到代码chunk

import { setPublicPath } from 'systemjs-webpack-interop'

setPublicPath('pro1', 2) //子应用的前缀。与主应用注册时的名称相同

3、子应用的vue.config.js配置

// Temporary until we can use https://github.com/webpack/webpack-dev-server/pull/2143
module.exports = {
    chainWebpack: config => {
      config.devServer.set('inline', false)
      config.devServer.set('hot', true)
      // Vue CLI 4 output filename is js/[chunkName].js, different from Vue CLI 3
      // More Detail: https://github.com/vuejs/vue-cli/blob/master/packages/%40vue/cli-service/lib/config/app.js#L29
      if (process.env.NODE_ENV !== 'production') {
        config.output.filename(`js/[name].js`)
        .libraryTarget('umd') // 打包方式  必须配置。这样systemjs才能正常加载子应用
        .end()
      }
      config.externals(['vue', 'vue-router']) //不打包vue等公共资源

      config
      .optimization.splitChunks({  //去掉默认的chunk-vendors  
        cacheGroups: {
          common: {
            name: `chunk-common`,
            minChunks: 2,
            priority: -20,
            chunks: 'initial',
            reuseExistingChunk: true
          }
        }
      })
    },
    filenameHashing: false
  }
  

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值