其实本来应该写个介绍的,但是我看到其他的文章写得很完善了,所以就来写写我在其中遇到的一些问题就好了。
安装single-spa请看沉末的这篇文章。
简单介绍下背景吧~
为什么要用single-spa
呢,是因为公司的项目需要拆项目了,这个时候就需要知道微前端的概念了,那么什么是微前端呢。
微前端架构是一种类似于微服务的架构,由ThoughtWorks 2016年提出,它将微服务的理念应用于浏览器端,即将 Web 应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。
由此带来的变化是,这些前端应用可以独立运行、独立开发、独立部署。
在项目中是运用single-spa
去搭建微前端框架的,在搭建框架之前,我们需要知道两个知识点,什么是single-spa
和importmap
。
而single-spa
是一个用于前端微服务化的JavaScript
前端解决方案。
特点:
我们先来看两段代码
import moment from 'moment';
import 'http://momentjs.com/downloads/moment.js';
在一个文件中我们写入如上代码,显然第一行是无法正常运行的,第二行是可以正常运行的,但如果我们想要第一行正常运行的话,importmap
就可以粉墨登场啦。只需要在html
文件书写如下:
<script type="importmap">
{
"imports": {
"moment": "https://momentjs.com/downloads/moment.js",
}
}
script>
就可以了。
但是现在浏览器并不支持,想要让它支持的话,需要引入system.js
。
<script type="systemjs-importmap">
{
"imports": {
"moment": "https://momentjs.com/downloads/moment.js",
}
}
script>
<script src="https://cdn.jsdelivr.net/npm/systemjs/dist/system.js">script>
而在single-spa
的使用过程中,我们需要用importmap
在根项目中引入所有的模块文件和子项目,从而在其余项目中可以进行模块的引用,就像上面说的那样,可以把moment
想象成一个子项目。
single-spa
用于将项目打包为可引用的模块。
其他的就不多加介绍了,具体可以看原作者@Joel Denning发的视频,需要上网。
在浏览器的console中输入
localStorage.setItem(‘devtools’, true);
这个小可爱就出现了。
在微服务的组件引用中,由于运用cdn引入,因此文件需要打包成单一的js
文件,而vue-cli3-service
(文件路径位于node_modules/_@[email protected]@@vue/cli-service/lib/config
, 并没有找到github
地址)内置了一些webpack
配置,在子项目的打包过程中需要把某些配置关掉,并且将其打包成支持system.js
的文件,我们需要做如下事情:
chunk-vendors
文件)mini-css-extract-plugin
(该插件会将组件中的css
抽离出来)代码如下
> vue.config.js
process.env.VUE_CLI_CSS_SHADOW_MODE = true; // 去除将css从js分出去的配置
module.exports = {
chainWebpack: config => {
config.optimization.delete('splitChunks') // 关闭代码分割
config.output
.filename('app.js')
.library('@[library]/[sub-project]')
.libraryTarget('amd') // 打包方式
.end()
}
...
}
但是上面都是屁话。。。。这些事情其实只要一个插件就可以解决了,原作者写了vue-cli-plugin-single-spa
这个插件,直接安装即可。
npm install vue-cli-plugin-single-spa -D
经过如上的过程打包之后,打包后的文件为/dist/js/app.js
,在原作者写的插件中,改写文件路径如下:
就可以了。
假如还是404
,可能项目被打包到了不同的路径,需要打开子项目的tab
在浏览器中查看文件地址。
需要注意的是vue-cli-plugin-single-spa
这个插件并没有处理文字等静态资源,因此尽管npm run build
没有显示静态资源被打包成单独的文件,事实上其还是被打包成了静态文件了。解决这个问题最好的方法是把element-ui
转化为cdn
引入的而不是通过node_module
引入的。
明明指向的是项目A,但是却渲染成了项目B。
插件中配置的文件路径错了,可能A项目是8080端口配置成了8081端口,在多项目开发的时候尤其容易出现该问题。
之前的我天真得以为可以将子项目变成一个router
的组件直接引入,但事实上是实现不了的。由于项目的耦合程度过大,依赖于各个插件,是无法将其打包成一个组件的。所以其实质上是两个并排的DOM
节点。但是我们可以实现一个假的效果。
在菜单栏的router
中设置,
{
path: '/',
component: Home,
name: 'home',
redirect: '/sub-project',
children: [{
path: 'sub-project/*',
name: 'sub-project',
}]
},
为什么要加星号呢,是为了解决另一个问题,不加通配符的话会导致navbar
无法正常匹配,如果sub-project
具有一些router
转换的话。
为了在子项目中能匹配相应的router
,需要设置
base: ‘sub-project’
接着在菜单栏中设置浮动,右边margin
相应的宽度就可以了。
从0实现一个single-spa的前端微服务
single-spa
vue-microfrontends
用微前端的方式搭建类单页应用
以上就是我遇到的问题,喜欢可以给一个小小的赞,谢谢~