single-spa结合vue项目初探
本次案例以vue-element-admin为例,验证single-spa的可接入性。根据single-spa的官网介绍,推荐将项目的所有文件(包括图片和css)等文件全部打包入一个js文件。但是这样我们原来的分包等打包优化都会变得没有意义,那么为什么要全部打入一个包呢?
因为single-spa的接入是以入口js文件接入的,而不是入口html文件,这样一来就会导致一些资源加载路径的错误,从而导致无法正常显示,但也并不是完全不可以。下面将一步步一起尝试。
安装依赖
我们需要安装几个依赖来方便接入single-spa
npm install -save single-spa-vue
npm install -save systemjs-webpack-interop // 根据需要引入
配置文件
首先修改vue-element-admin的一些文件,首先是main.js,这里只列举新增的代码块,其余保持不变,唯一需要变得是删除Vue实例化的部分(即 new Vue(…))。
import "./set-public-path";
import singleSpaVue from "single-spa-vue";
const vueLifecycles = singleSpaVue({
Vue,
appOptions: {
render: h => h(App),
router,
store
}
});
export const bootstrap = vueLifecycles.bootstrap;
export const mount = vueLifecycles.mount;
export const unmount = vueLifecycles.unmount;
然后在main.js同级目录下添加set-public-path.js文件,这个文件的作用是可以简化文件的引用路径,这样在项目跑起来后就可以方便引入打包后的文件(只是在运行时简化),如果是先打包后引入的话就不需要这个文件。
import { setPublicPath } from "systemjs-webpack-interop";
setPublicPath("vueAdmin", 2);
修改vue.config.js
这里修改打包方式,这部分是我尝试过之后可用的打包方式,暂且以这个为例。
// 只保留如下 chainWebpack 配置,其余的删除
chainWebpack: config => { // 保留原项目处理svg的loader
config.devServer.set("inline", false);
config.devServer.set("hot", true);
config.module
.rule("svg")
.exclude.add(resolve("src/icons"))
.end();
config.module
.rule("icons")
.test(/\.svg$/)
.include.add(resolve("src/icons"))
.end()
.use("svg-sprite-loader")
.loader("svg-sprite-loader")
.options({
symbolId: "icon-[name]"
})
.end();
// config.externals(['vue', 'vue-router']) 如果是在外部统一引入则开启这行
},
filenameHashing: false // 禁用hash文件名
然后执行命令打包,我这里是打包到dist目录下,这里显示++的都是打包后手动新增的文件
└─static
├─fonts
├─img
├─js
└─static ++
├─fonts ++
├─img ++
└─js ++
添加single-spa项目
新建一个文件夹执行npm init
然后修改pakage.json内容如下
{
"name": "single-spa",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"serve": "serve -s -l 5000"
},
"devDependencies": {
"serve": "^11.3.2"
},
"author": "",
"license": "ISC"
}
新建index.html
文件中vueAdmin的路径为vue项目打包后的dist目录下起的服务
Coexisting Vue Microfrontends"imports": {
"single-spa": "https://cdnjs.cloudflare.com/ajax/libs/single-spa/4.3.7/system/single-spa.min.js",
"vueAdmin": "http://10.118.37.41:8080/static/js/app.js"
}
}
rel="preload"
href="https://cdnjs.cloudflare.com/ajax/libs/single-spa/4.3.7/system/single-spa.min.js"
as="script"
crossorigin="anonymous"
/>
System.import("vueAdmin").then((res) => {
console.log(res);
});
Promise.all([System.import("single-spa")]).then(function (modules) {
var singleSpa = modules[0];
singleSpa.registerApplication(
"vueAdmin",
() => System.import("vueAdmin"),
(location) => true
);
singleSpa.start();
});
})();
show-when-local-storage="overrides-ui"
>
然后执行npm run serve就可以在浏览器中看到效果,并且是按需加载
结论:以js入口的方式并不是不可以分包加载,只不过需要我们修改打包出来的文件的文件夹层级