老项目vue2.6.14的前端微服务改造方案
微前端思想
- 基于接口协议:子应用按照协议导出几个接口,主应用在运行过程中调用子应用导出的这几个接口
- 基于沙箱隔离:主应用创建一个隔离环境,让子应用基本不用考虑自己是在什么环境下运营,按照普通的开发思路进行开发即可
- 基于模块协议:主应用把子应用当作一个模块,和模块的使用方式无异
方案选择
- 路由分发静态资源与iframe结合,懂得都懂,问题很大
- 阿里qiankun(基于single SPA):对项目侵入性比较大
- 京东MicroApp(基于Web Components) 需要引入脚手架改造
- 腾讯wujie(基于Web Components) ,刚开源,未深入了解
- webpack5(module-federation)微服务项目,结合老项目只需升级vue-service到5.0以上即可使用
实现思路
- 主项目订阅服务
- 子项目发布服务
- 架构分为基础组件服务,中层业务模块,外部门户。
项目改造内容
-
升级部分依赖,webpack版本升级到5以上,使用其module-federation新特性
"@vue/cli-service": "~5.0.0", "vue":"^2.7.14",
- 修改入口js
新增bootstrap.js用于存放原入口js文件(main.js),mainjs修改点
window.componentsUrl = "http://localhost:1006";
import bootstrap from "./bootstrap";
bootstrap;
-
修改vue.config.js实现bootstrap.js懒加载
{ test: /bootstrap.js$/, loader: "bundle-loader", options: { lazy: true, }, },
-
主项目chainWebpack示例(基于本地服务ip订阅):
config .plugin("module-federation-plugin") .use(require("webpack").container.ModuleFederationPlugin, [ { name: "web", remotes: { app1: "app1@http://localhost:8084/remoteEntry.js", }, }, ]);
-
子项目chainWebpack示例(发布子项目组件或者页面)
config .plugin("module-federation-plugin") .use(require("webpack").container.ModuleFederationPlugin, [ { name: "app1", // 模块名称 filename: "remoteEntry.js", exposes: { // 对外暴露的组件 "./HelloWorld": "./src/components/HelloWorld.vue", }, }, ]);
-
dev代理配置(路由重定向到所订阅的服务)
"/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服务发布页面
exposes: { "./workflowMatters":"./src/views/workflow/workflowMatters/index.vue", }
-
zc-system-web门户服务订阅服务
remotes: { workflow:"workflow@[window.workflowUrl]/workflowRemoteEntry.js", },
-
main.js注册工作流服务路径,并配置代理
window.workflowUrl = "http://localhost:9001";
组件模块共享示例
-
zc-components-web服务暴露出组件vue.config.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
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的完整性
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net