1.什么是微前端
在说什么是微前端的之前我们先来思考一下什么是微服务,微服务是一种为了降低服务端耦合的架构方式(为了解决庞大的一整块后端服务带来的变更与扩展方面的限制)
微服务是面向服务架构(SOA)的一种变体,把应用程序设计成一系列松耦合的细粒度服务,并通过轻量级的通信协议组织起来具体地,将应用构建成一组小型服务。这些服务都能够独立部署、独立扩展,每个服务都具有稳固的模块边界,甚至允许使用不同的编程语言来编写不同服务,也可以由不同的团队来管理
那么引用微服务的架构思想,顾名思义微前端就是将多个前端应用分解成一些更小、更简单的能够独立开发、测试、部署的小块,而在用户看来仍然是内聚的单个产品
2.微前端有什么特点
2.1:降低代码耦合,易于维护
2.2:各子应用独立发布部署
2.3:提升代码可复用性
2.4:更容易进行单元测试
2.5:减少团队之间依赖
3.微前端的实现方案
3.1 iframe
优点:1.近乎完美的代码隔离机制
2.学习成本几乎为0
缺点:1.iframe内部独立文档流,modal组件样式巨丑
2.iframe阻塞外层框架渲染
3.浏览器后退按钮失效
4.与框架共享http连接数
5.浏览器url需要做额外处理
3.2 Nginx
实现:通过配置ngin拦截指定的url返回对应的html模板
优点:1.实现简单
2.技术栈独立
缺点:1.需要额外的Nginx配置
2.与服务端耦合
3.3single-spa
优点:1.纯前端解决方案
2.可以使用多种技术栈
3.完善的生态
4.丝滑的通信
缺点:1.上手成本高
2.需要改造现有应用
3.样式隔离需要单独处理
在这里我们主要讨论第三种实现方案
4.具体实现
4.1 基于single-spa,single-spa-vue,探索主应用为vue,子应用为vue的实现方案
先来看看我们的项目结构
base为主应用,app1为子应用
接下来我们先来看看主应用
在基础的vue项目中多出来了一个sing-spa-conf.js的文件,没错,这个文件就是我们注册子应用的文件,这个文件主要做了一下几件事:
1.配置子应用信息(子应用必须有独立的应用名)
2.匹配子应用的baseUrl, 加载对应的js文件(通过打包生成的manifest.json,去获取子应用的js列表),动态插入到页面
3.注册子应用
完整代码如图:
到这里,我们应用的配置工作就完成了,然后我们需要给子应用一个容器,在App.vue文件中添加如下代码:
其中id为microApp的div为子应用的容器,上面的router-view是主应用的路由容器(主应用也会有自己的路由)
到此主应用我们就搞完了(其实还没完。。。)
接下来我们继续,来看看子应用的改造,先来看看子应用的目录结构:
咦,好像和一般的应用看起来也没啥区别(这你就看的不透了),我们一起来看看内里乾坤。首先来看看我们的项目入口文件main.js
这里主要做了两件事,一个是将子应用的bootstrap,mount, unmount生命周期函数导出,导出的目的提供给主应用去动态的加载和卸载子应用。另外一件事是判断在非嵌入主应用环境独立运行。
入口文件处理完了之后,再接下来我们还得修改一下打包策略,入下图
使用stats-webpack-plugin插件(打包时生成对应的资源清单)
修改打包输出类型(这个要是看不懂的话,请点击https://v4.webpack.docschina.org/configuration/output/#output-library恶补)
将css设置为采用<style>标签的引入方式
到此子项目的改造就算完成了。
到这里,仿佛一切都很顺利(激动中。。。),启动项目打开页面,额,显示是显示了,可是这样式怎么冲突了,回顾一下,我们将子项目的样式全部设置为使用<style>的方式引入的,然后子项目和主项目处在一个文档流中,这好像是有问题呀,那该怎么解决呢(苦思冥想)。
最后我们采用postcss-selector-namespace这个postcss的plugin,这个插件是干什么的呢,它可以将我们项目内定义的样式集中统一处理,这里我们看一下是怎么处理的,在postcss.config.js内我们这么处理
我们在这里给所有的css添加统一的前缀来实现样式的隔离。(tips: 在样式前面添加:root可以避免统一处理,这会很有用。)
到此,我们所有的改造就完成了。下一篇我们将深入了解single-spa框架,来看看它是如何实现的。