single-spa结合vue项目初探

    技术2024-02-21  107

    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目录下起的服务

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <title>Coexisting Vue Microfrontends</title> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="importmap-type" content="systemjs-importmap" /> <script type="systemjs-importmap"> { "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" } } </script> <link rel="preload" href="https://cdnjs.cloudflare.com/ajax/libs/single-spa/4.3.7/system/single-spa.min.js" as="script" crossorigin="anonymous" /> <script src="https://unpkg.com/import-map-overrides@1.7.2/dist/import-map-overrides.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.1.1/system.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.1.1/extras/amd.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.1.1/extras/named-exports.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.1.1/extras/named-register.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.1.1/extras/use-default.min.js"></script> </head> <body> <script> (function () { 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(); }); })(); </script> <!-- See https://github.com/joeldenning/import-map-overrides#user-interface --> <import-map-overrides-full show-when-local-storage="overrides-ui" ></import-map-overrides-full> </body> </html>

    然后执行npm run serve就可以在浏览器中看到效果,并且是按需加载

    结论:以js入口的方式并不是不可以分包加载,只不过需要我们修改打包出来的文件的文件夹层级

    Processed: 0.014, SQL: 9