Skip to content
快速索引

老项目vue(2.6.14)的前端微服务改造方案

微前端思想

  • 基于接口协议:子应用按照协议导出几个接口,主应用在运行过程中调用子应用导出的这几个接口
  • 基于沙箱隔离:主应用创建一个隔离环境,让子应用基本不用考虑自己是在什么环境下运营,按照普通的开发思路进行开发即可
  • 基于模块协议:主应用把子应用当作一个模块,和模块的使用方式无异

方案选择

  • 路由分发静态资源与iframe结合,懂得都懂,问题很大
  • 阿里qiankun(基于single SPA):对项目侵入性比较大
  • 京东MicroApp(基于Web Components) 需要引入脚手架改造
  • 腾讯wujie(基于Web Components) ,刚开源,未深入了解
  • webpack5(module-federation)微服务项目,结合老项目只需升级vue-service到5.0以上即可使用

实现思路

  • 主项目订阅服务
  • 子项目发布服务
  • 架构分为基础组件服务,中层业务模块,外部门户, 图片

项目改造内容

  • 升级部分依赖,webpack版本升级到5以上,使用其module-federation新特性
json
"@vue/cli-service": "~5.0.0",
    "vue":"^2.7.14",
  • 修改入口js 新增bootstrap.js用于存放原入口js文件(main.js),mainjs修改点
js
window.componentsUrl = "http://localhost:1006";
    import bootstrap from "./bootstrap";
    bootstrap;
  • 修改vue.config.js实现bootstrap.js懒加载
js
{
     test: /bootstrap\.js$/,
     loader: "bundle-loader",
     options: {
       lazy: true,
     },
   },
  • 主项目chainWebpack示例(基于本地服务ip订阅):
js
config
      .plugin("module-federation-plugin")
      .use(require("webpack").container.ModuleFederationPlugin, [
        {
          name: "web",
          remotes: {
            app1: "app1@http://localhost:8084/remoteEntry.js",
          },
        },
      ]);
  • 子项目chainWebpack示例(发布子项目组件或者页面)
js
config
      .plugin("module-federation-plugin")
      .use(require("webpack").container.ModuleFederationPlugin, [
        {
          name: "app1", // 模块名称
          filename: "remoteEntry.js",
          exposes: {
            // 对外暴露的组件
            "./HelloWorld": "./src/components/HelloWorld.vue",
          },
        },
      ]);
  • dev代理配置(路由重定向到所订阅的服务)
js
"/componentsService": {
        changeOrigin: true,
        target: process.env.VUE_APP_OA_componentsUrl,
        pathRewrite: {
          ["^" + "/componentsService"]: "",
        },
      },
      "/workflowService": {
        changeOrigin: true,
        target: process.env.VUE_APP_workflowUrl,
        pathRewrite: {
          ["^" + "/workflowService"]: "",
        },
      },

页面模块共享示例

  • zc-workflow-web服务发布页面
js
exposes: {
       "./workflowMatters":"./src/views/workflow/workflowMatters/index.vue",
    }
  • zc-system-web门户服务订阅服务
js
remotes: {
       workflow:"workflow@[window.workflowUrl]/workflowRemoteEntry.js",
    },
  • main.js注册工作流服务路径,并配置代理
js
window.workflowUrl = "http://localhost:9001";

组件模块共享示例

  • zc-components-web服务暴露出组件vue.config.js
js
config
            .plugin("module-federation-plugin")
            .use(require("webpack").container.ModuleFederationPlugin, [
              { ...setupModule },
            ]);
      moduleSetUp.js
      const dependencies = require("./package.json").dependencies;
      module.exports = {
        name: "oa_components", // 模块名称
        filename: "remoteEntry.js",
        exposes: {
          "./ThemeSearchBar": "./src/components/searchBar/src/index.vue",
        },
        shared: [
          "vuex",
          "vue-router",
          "element-ui",
          {
            vue: {
              eager: true,
              singleton: true,
              requiredVersion: dependencies["vue"],
            },
          },
        ],
      };
  • zc-workflow-web工作流服务服务引用组件vue.config.js
js
remotes: {
                  oa_components:
                    "oa_components@[window.oa_componentsUrl]/remoteEntry.js",
                },

      import ThemeSearchBar from "oa_components/ThemeSearchBar";

      export default {
        install(Vue) {
          Vue.component(ThemeSearchBar.name, ThemeSearchBar);
        },
      };

nginx配置

  • 根据需要独立ip通过文件路径代理
  • 不同ip通过proxy_pass代理
  • 不同服务器通过proxy_pass

总结

优点

  • 组件服务可以安装到静态资源服务器,与文档,字体,icon库统一配置。
  • 每个模块都是一个服务,不同模块业务解耦,独立安装部署,拆解灵活度增高,新需求按需引入即可。
  • module-federation按需加载与合理配置资源服务,中大型项目首屏加载启动速度10秒内。

缺点

  • 需自行管理配置样式隔离
  • 需要部署服务增多,项目拆分颗粒度要审慎把握
  • 单个模块不能split,需保证runtimejs的完整性

Last updated: