我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Vue技术栈的微前端方案分析

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Vue技术栈的微前端方案分析

这篇文章主要介绍“Vue技术栈的微前端方案分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Vue技术栈的微前端方案分析”文章能帮助大家解决问题。

背景介绍

对于大型前端项目,比如公司内部管理系统(一般包括 OA、HR、CRM、会议预约等系统),如果将所有业务放在一个前端项目里,随着业务功能不断增加,就会导致如下这些问题:

  • 代码规模庞大,导致编译时间过长,开发、打包速度越来越慢

  • 项目文件越来越多,导致查找相关文件变得越来越困难

  • 某一个业务的小改动,导致整个项目的打包和部署

方案介绍

preload-routesasync-routes 是目前笔者所在团队使用的微前端方案,最终会将整个前端项目拆解成一个主项目和多个子项目,其中两者作用如下:

  • 主项目:用于管理子项目的路由切换、注册子项目的路由和全局 Store 层、提供全局库和方法

  • 子项目:用于开发子业务线业务代码,一个子项目对应一个子业务线,并且包含两端(PC + Mobile)代码和复用层代码(项目分层中的非视图层)

将整个前端项目按照业务线拆分出多个子项目,每个子项目都是独立的仓库,只包含了单个业务线的代码,可以进行独立开发和部署,降低了项目维护的复杂度。

采用这套方案,使得我们的前端项目不仅保有了横向上(多个子项目)的扩展性,又拥有了纵向上(单个子项目)的复用性。那么这套方案具体是怎么实现的呢?下面就详细说明方案的实现机制。

在讲解之前,首先明确下这套方案有两种实现方式,一种是预加载路由,另一种是懒加载路由,可以根据实际需求选择其中一个即可。接下来就分别介绍这两种方式的实现机制。

实现机制

预加载路由方式

preload-routes

子项目按照 vue-cli 3 的 library 模式进行打包,以便后续主项目引用

注:在 library 模式中, Vue  是外置的。这意味着包中不会有  Vue ,即便你在代码中导入了  Vue 。如果这个库会通过一个打包器使用,它将尝试通过打包器以依赖的方式加载  Vue ;否则就会回退到一个全局的 Vue  变量。

在编译主项目的时候,通过 InsertScriptPlugin 插件将子项目的入口文件 main.js 以 script 标签形式插入到主项目的 html 中

注:务必将子项目的入口文件 main.js 对应的 script 标签放在主项目入口文件 app.jsscript 标签之上,这是为了确保子项目的入口文件先于主项目的入口文件代码执行,接下来的步骤就会明白为什么这么做。

再注:本地开发环境下项目的入口文件编译后的 main.js 是保存在内存中的,所以磁盘上看不见,但是可以访问。

InsertScriptPlugin 核心代码如下:

compiler.hooks.compilation.tap('InsertScriptWebpackPlugin', compilation => {  compilation.hooks.htmlWebpackPluginBeforeHtmlProcessing.tap(    'InsertScriptWebpackPlugin',    htmlPluginData => {      const {        assets: { js }      } = htmlPluginData;      // 将传入的 js 以 script 标签形式插入到 html 中      // 注意:需要将子项目的入口文件 main.js 放在主项目入口文件 app.js 之前,因为需要子项目提前将自己的 route list 注册到全局上      js.unshift(...self.files);    }  );});

主项目的 html 要访问子项目里的编译后的 js / css 等资源,需要进行代理转发

  • 如果是本地开发时,可以通过 webpack 提供的 proxy,例如:

const PROXY = {  '/app-a/': {    target: 'http://localhost:10241/'  }};
  • 如果是线上部署时,可以通过 nginx 转发或者将打包后的主项目和子项目放在一个文件夹中按照相对路径引用。

当浏览器解析 html 时,解析并执行到子项目的入口文件 main.js将子项目的 route list 注册到 Vue.share.routes 上,以便后续主项目将其合并到总的路由中。

子项目 main.js 代码如下:(为了尽量减少首次主项目页面渲染时加载的资源,子项目的入口文件建议只做路由挂载)

import Vue from 'vue';import routes from './routes';const share = (Vue.__share__ = Vue.__share__ || {});const routesPool = (share.routes = share.routes || {});// 将子项目的 route list 挂载到 Vue.__share__.routes 上,以便后续主项目将其合并到总的路由中routesPool[process.env.VUE_APP_NAME] = routes;

继续向下解析 html,解析并执行到主项目 main.js 时,从 Vue.share.routes 获取所有子项目的 route list,合并到总的路由表中,然后初始化一个 vue-router实例,并传入到 new Vue 内

相关关键代码如下

// 从 Vue.__share__.routes 获取所有子项目的 route list,合并到总的路由表中const routes = Vue.__share__.routes;export default new Router({  routes: Object.values(routes).reduce((acc, prev) => acc.concat(prev), [    {      path: '/',      redirect: '/app-a'    }  ])});

到此就实现了单页面应用按照业务拆分成多个子项目,直白来说子项目的入口文件 main.js 就是将主项目和子项目联系起来的桥梁。

另外如果需要使用 vuex,则和 vue-router 的顺序恰好相反(先主项目后子项目):

首先在主项目的入口文件中初始化一个 store 实例 new Vuex.Store,然后挂在到 Vue.__share__.store

然后在子项目的 App.vue 中获取到 Vue.__share__.store 并调用 store.registerModule(‘app-x', store),将子项目的 store 作为子模块注册到 store

懒加载路由方式

async-routes

懒加载路由,顾名思义,就是说等到用户点击要进入子项目模块,通过解析即将跳转的路由确定是哪一个子项目,然后再异步去加载该子项目的入口文件 main.js(可以通过 systemjs 或者自己写一个动态创建 script 标签并插入 body 的方法)。加载成功后就可以将子项目的路由动态添加到主项目总的路由里了。

主项目 router.js 文件中定义了在 vue-router 的 beforeEach 钩子去拦截路由,并根据即将跳转的路由分析出需要哪个子项目,然后去异步加载对应子项目入口文件,下面是核心代码:

const cachedModules = new Set();router.beforeEach(async (to, from, next) => {  const [, module] = to.path.split('/');  if (Reflect.has(modules, module)) {    // 如果已经加载过对应子项目,则无需重复加载,直接跳转即可    if (!cachedModules.has(module)) {      const { default: application } = await window.System.import(        modules[module]      );      if (application && application.routes) {        // 动态添加子项目的 route-list        router.addRoutes(application.routes);      }      cachedModules.add(module);      next(to.path);    } else {      next();    }    return;  }});

子项目的入口文件 main.js 仅需要将子项目的 routes 暴露给主项目即可,代码如下:

import routes from './routes';export default {  name: 'javascript',  routes,  beforeEach(from, to, next) {    console.log('javascript:', from.path, to.path);    next();  }};

注意:这里除了暴露 routes 方法外,另外又暴露了 beforeEach 方法,其实就是为了支持通过路由守卫对子项目进行页面权限限制,主项目拿到这个子项目的 beforeEach,可以在 vue-routerbeforeEach 钩子执行,具体代码请参考 async-routes

除了主项目和子项目的交互方式不同,代理转发子项目资源、vuex store 注册等和上面的预加载路由完全一致。

优缺点

下面谈下这套方案的优缺点:

优点

  • 子项目可单独打包、单独部署上线,提升了开发和打包的速度

  • 子项目之间开发互相独立,互不影响,可在不同仓库进行维护,减少的单个项目的规模

  • 保持单页应用的体验,子项目之间切换不刷新

  • 改造成本低,对现有项目侵入度较低,业务线迁移成本也较低

  • 保证整体项目统一一个技术栈

缺点

  • 主项目和子项目需要共用一个 Vue 实例,所以无法做到某个子项目单独使用最新版  Vue (例如 Vue3)或者  React

部分问题解答

1.如果子项目代码更新后,除了打包部署子项目之外,还需要打包部署主项目吗?

不需要更新部署主项目。这里有个 trick 上文忘记提及,就是子项目打包后的入口文件并没有加上 chunkhash,直接就是 main.js(子项目其他的 js 都有 chunkhash)。也就是说主项目只需要记住子项目的名字,就可以通过 subapp-name/main.js 找到子项目的入口文件,所以子项目打包部署后,主项目并不需要更新任何东西。

2.针对第二个问题中子项目入口文件 main.js 不使用 chunkhash 的话,如何防止该文件始终被缓存呢?

可以在静态资源服务器端针对子项目入口文件设置强制缓存为不缓存,下面是服务器为 nginx 情况的相关配置:

location / {    set $expires_time 7d;    ...    if ($request_uri ~* \/(contract|meeting|crm)-app\/main.js(\?.*)?$) {        # 针对入口文件设置 expires_time -1,即expire是服务器时间的 -1s,始终过期        set $expires_time -1;    }    expires $expires_time;    ...}

关于“Vue技术栈的微前端方案分析”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网行业资讯频道,小编每天都会为大家更新不同的知识点。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Vue技术栈的微前端方案分析

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Vue技术栈的微前端方案分析

这篇文章主要介绍“Vue技术栈的微前端方案分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Vue技术栈的微前端方案分析”文章能帮助大家解决问题。背景介绍对于大型前端项目,比如公司内部管理系统(一般
2023-06-27

Vue.js前端项目多语言方案的示例分析

这篇文章给大家分享的是有关Vue.js前端项目多语言方案的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、通常有哪些内容需要处理总的来说,一个Web应用中,需要做多语言切换的内容常见的包括如下方面:1、
2023-06-20

spring boot+vue 的前后端分离与合并方案实例详解

springboot和vue结合的方案网络上的主要有以下两种:1. 【不推荐】在html中直接使用script标签引入vue和一些常用的组件,这种方式和以前传统的开发是一样的,只是可以很爽的使用vue的双向数据绑定,这种方式只适合于普通的全
2023-05-30

MongoDB技术开发中遇到的分布式事务问题解决方案分析

MongoDB技术开发中遇到的分布式事务问题解决方案分析随着互联网的迅猛发展,分布式系统变得越来越重要。在分布式系统中,数据库的一致性和事务的处理变得尤为关键。MongoDB作为一种流行的NoSQL数据库,也面临着分布式事务的挑战。本文将分
2023-10-22

MongoDB技术开发中遇到的数据分片平衡问题解决方案分析

MongoDB技术开发中遇到的数据分片平衡问题解决方案分析,需要具体代码示例摘要:在使用MongoDB进行大规模数据存储时,数据分片是必不可少的技术手段。然而,在数据量增长的过程中,由于数据分片的不均衡或者其他原因,可能会导致数据分片的不平
2023-10-22

MongoDB技术开发中遇到的集群管理问题解决方案分析

MongoDB技术开发中遇到的集群管理问题解决方案分析摘要:随着大数据和云计算的快速发展,MongoDB作为一种流行的非关系型数据库,被广泛应用于大规模数据存储和处理的场景中。然而,在实际的开发过程中,MongoDB集群管理问题成为开发者面
2023-10-22

MongoDB技术开发中遇到的数据更新问题解决方案分析

MongoDB技术开发中遇到的数据更新问题解决方案分析摘要:在MongoDB的应用开发中,数据更新是非常常见的操作。但是,由于MongoDB的灵活性和复杂性,开发人员可能会遇到各种各样的数据更新问题。本文将针对一些常见的数据更新问题进行分析
2023-10-22

MongoDB技术开发中遇到的数据迁移问题解决方案分析

MongoDB技术开发中遇到的数据迁移问题解决方案分析摘要:随着数据量的不断增长和业务需求的变化,数据迁移成为了开发中一个必须面对的问题。本文将针对使用MongoDB进行数据迁移时可能遇到的问题进行分析,并给出解决方案,包含具体的代码示例。
2023-10-22

MongoDB技术开发中遇到的连接失败问题解决方案分析

MongoDB技术开发中遇到的连接失败问题解决方案分析引言:MongoDB是一种非关系型数据库,在开发过程中,我们经常会遇到连接失败的问题。本文将分析连接失败的原因,并给出解决方案和具体代码示例,帮助读者更好地应对这类问题。一、连接失败原因
2023-10-22

MongoDB技术开发中遇到的事务管理问题解决方案分析

MongoDB技术开发中遇到的事务管理问题解决方案分析随着现代应用程序变得越来越复杂和庞大,对数据的事务处理需求也越来越高。作为一种流行的NoSQL数据库,MongoDB在数据管理方面有着出色的性能和扩展性。然而,MongoDB在数据一致性
2023-10-22

MongoDB技术开发中遇到的连接超时问题解决方案分析

MongoDB技术开发中遇到的连接超时问题解决方案分析摘要:在MongoDB技术开发过程中,由于网络或服务器等因素,经常会遇到连接超时的问题。本文将从断开连接的原因分析、解决方案以及具体的代码示例三个方面进行探讨,帮助开发者解决连接超时问题
2023-10-22

MongoDB技术开发中遇到的并发访问问题解决方案分析

MongoDB技术开发中遇到的并发访问问题解决方案分析引言:在当今互联网时代,数据的规模和复杂性不断增长,使得数据库系统面临着越来越严峻的并发访问问题。尤其在大数据领域,MongoDB作为一款非常受欢迎的NoSQL数据库技术,也面临着并发访
2023-10-22

MongoDB技术开发中遇到的查询性能问题解决方案分析

MongoDB技术开发中遇到的查询性能问题解决方案分析摘要:MongoDB作为一种非关系型数据库,在大规模数据存储和查询应用中广泛应用。然而,在实际的技术开发过程中,我们经常会面临查询性能不佳的问题。本文将详细分析一些常见的查询性能问题,并
2023-10-22

MongoDB技术开发中遇到的数据备份问题解决方案分析

标题:MongoDB技术开发中遇到的数据备份问题解决方案分析摘要:在MongoDB技术开发中,数据备份是非常重要的。本文将首先介绍MongoDB的数据备份背景及其重要性。然后,我们将分析在开发中可能遇到的数据备份问题,包括备份性能、备份容量
2023-10-22

MongoDB技术开发中遇到的文本搜索问题解决方案分析

MongoDB技术开发中遇到的文本搜索问题解决方案分析,需要具体代码示例摘要:在现代应用程序中,文本搜索是一个常见且重要的功能需求。然而,在处理大量文本数据时,传统的搜索方式效率较低。本文将对MongoDB在文本搜索方面的功能进行分析,并提
2023-10-22

MongoDB技术开发中遇到的数据过期问题解决方案分析

MongoDB技术开发中遇到的数据过期问题解决方案分析摘要:在MongoDB技术开发过程中,对于一些有时效性的数据而言,如何解决数据过期的问题是一个重要的考虑因素。本文将针对MongoDB中的数据过期问题进行分析,并提供具体的解决方案和代码
2023-10-22

MongoDB技术开发中遇到的查询缓存问题解决方案分析

MongoDB技术开发中遇到的查询缓存问题解决方案分析摘要:在MongoDB技术开发中,查询缓存问题是一种常见的困扰开发人员的难题。本文将从查询缓存的原理入手,详细分析了查询缓存问题的原因以及可能的解决方案,并给出了具体的代码示例。一、查询
2023-10-22

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录