single-spa的简单介绍与遇到的问题小结

其实本来应该写个介绍的,但是我看到其他的文章写得很完善了,所以就来写写我在其中遇到的一些问题就好了。

安装single-spa请看沉末的这篇文章

背景

简单介绍下背景吧~

为什么要用single-spa呢,是因为公司的项目需要拆项目了,这个时候就需要知道微前端的概念了,那么什么是微前端呢。

微前端服务

微前端架构是一种类似于微服务的架构,由ThoughtWorks 2016年提出,它将微服务的理念应用于浏览器端,即将 Web 应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。

由此带来的变化是,这些前端应用可以独立运行、独立开发、独立部署。

在项目中是运用single-spa去搭建微前端框架的,在搭建框架之前,我们需要知道两个知识点,什么是single-spaimportmap

single-spa

single-spa是一个用于前端微服务化的JavaScript前端解决方案。

特点:

  • (兼容各种技术栈)在同一个页面中使用多种技术框架(React, Vue, AngularJS, Angular, Ember等任意技术框架),并且不需要刷新页面.
  • (无需重构现有代码)使用新的技术框架编写代码,现有项目中的代码无需重构.
  • (更优的性能)每个独立模块的代码可做到按需加载,不浪费额外资源.
    每个独立模块可独立运行.

importmap

我们先来看两段代码

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发的视频,需要🔬上网。

遇到的问题

怎么打开importmap的插件

在浏览器的console中输入

localStorage.setItem(‘devtools’, true);

这个小可爱就出现了。

子项目打包

在微服务的组件引用中,由于运用cdn引入,因此文件需要打包成单一的js文件,而vue-cli3-service(文件路径位于node_modules/_@vue_cli-service@4.3.1@@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

子项目的文件路径404了

经过如上的过程打包之后,打包后的文件为/dist/js/app.js,在原作者写的插件中,改写文件路径如下:

就可以了。

假如还是404,可能项目被打包到了不同的路径,需要打开子项目的tab在浏览器中查看文件地址。

element-ui 图标显示不出

需要注意的是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
用微前端的方式搭建类单页应用




以上就是我遇到的问题,喜欢可以给一个小小的赞,谢谢~

作为一个AI语言模型,我无法像人类一样编写代码。但是我可以为您提供single-spa的应用的基本理解和示例。 Single-spa是一个前端微服务框架,它允许您在同一个页面上使用多个JavaScript框架,例如React、Angular和Vue等。它提供了一个统一的入口点,负责管理不同的应用程序,从而使多个应用程序之间的通信更轻松。 下面是一个简单single-spa应用示例,它使用React和Vue框架: 1. 首先,您需要使用npm安装single-spa: npm install single-spa --save 2. 然后,创建一个React应用程序: import React from 'react'; import ReactDOM from 'react-dom'; class ReactApp extends React.Component { render() { return ( <div> <h1>React App</h1> <p>Hello, World!</p> </div> ); } } ReactDOM.render(<ReactApp />, document.getElementById('react-app')); 3. 接下来,创建一个Vue应用程序: import Vue from 'vue'; import App from './App.vue'; new Vue({ el: '#vue-app', render: h => h(App) }); 4. 最后,在单一页面应用程序中使用这两个应用程序: import { registerApplication, start } from 'single-spa'; registerApplication( 'react-app', () => import('./react-app'), () => location.pathname === '/react' ); registerApplication( 'vue-app', () => import('./vue-app'), () => location.pathname === '/vue' ); start(); 这将在页面上注册两个应用程序:一个React应用程序和一个Vue应用程序。它使用location.pathname来检查当前路径是否与每个应用程序的路径匹配。如果是,则加载相应的应用程序。 如果您想了解更多关于single-spa的信息,请访问官方网站:https://single-spa.js.org/
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值