微前端框架 single-spa

一、什么是微前端?
微前端一词第一次出现是在工作思维(ThoughtWorks)2016年的技术雷达( Technology Radar )中。微前端是一种架构,是将整个巨石应用拆分成多个可独立开发、部署、上线,运行的小型应用(子应用),对外暴露一个控制台应用(父应用)来统一管理各个子应用的运行状态,多个子应用间在用户无感情况下往复切换。

现代应用痛点:

  • 项目中的组件和功能模块会越来越多,导致整个项目的打包速度变慢;
  • 因为文件夹的数量会随着功能模块的增多而增多,查找代码会变得越来越慢;
  • 如果只改动其中一个模块的情况,需要把整个项目重新打包上线;
  • 目录层级和模块层级过深而且文件又多,定位文件会越来越慢;
  • 所有的项目都只能使用同一技术框架如:react、vue等;

微前端的优势

  • 无技术栈限制:主框架不限制接入应用的技术栈,子应用具备完全自主权
  • 独立开发,独立部署,子应用的仓库独立,前后端可独立进行开发,部署完成后主框架自动完成同步更新
  • 独立运行:每个项目都可以作为一个完整的单独项目去运行。独立运行时,每个子应用之间状态隔离,运行时状态不共享

二、微前端架构解决方案

  • 2018 single-spa 是一个用于前端微服务化的 javascript 前端解决方案,(本身没有处理样式隔离,js 执行隔离)实现了路由的劫持和应用加载;
  • 2019 qiankun 基于 single-spa 提供了更加开箱即用的 api(single-spa+sandbox+import-html-entry)做到了,技术栈无关,并且接入简单。

三、single-spa

解决的问题
single-spa 实现了路由劫持和应用加载的功能: 监听路由加载子模块
Single-spa 是一个将多个单页面应用聚合为一个整体应用的 JavaScript 微前端框架。
基座提供注册逻辑、子应用提供三个协议接入方法和打包格式
子应用可以独立部署,运行时动态加载主子应用完全解耦,技术栈无关,靠的是协议接入(子应用必须导出 bootstrap,mount,unmount 方法)

基座
在基座里我们调用single-spa提供给我们的registerApplication和start的方法

singleSpa.registerApplication:这是注册子项目的方法。参数如下:

appName: 子项目名称
applicationOrLoadingFn: 子项目注册函数,用户需要返回 single-spa 的生命周期对象。后面我们会介绍single-spa的生命周期机制
activityFn: 回调函数入参 location 对象,可以写自定义匹配路由加载规则。

singleSpa.start:这是启动函数。
注意:父项目的 vue-router 要开启history模式。

子项目
如果想注册为一个子项目,还需要 single-spa-vue 的包装。
在main.js中引入 single-spa-vue,传入Vue对象和vue.js挂载参数,就可以实现注册。它会返回一个对象,里面有single-spa 需要的生命周期函数。使用export导出即可。
子项目最重要的就是提供三个方法 bootstrap、mount、unmount 和 打包格式

import singleSpaVue from "single-spa-vue";
import Vue from 'vue'

const vueOptions = {
    el: "#microApp",
    router,
    store,
    render: h => h(App)
};

// singleSpaVue包装一个vue微前端服务对象
const vueLifecycles = singleSpaVue({
    Vue,
    appOptions: vueOptions
});

// 导出生命周期对象
export const bootstrap = vueLifecycles.bootstrap; // 启动时
export const mount = vueLifecycles.mount; // 挂载时
export const unmount = vueLifecycles.unmount; // 卸载时

webpack的处理
只是导出了,还需要挂载到window。
在项目目录下新建 vue.config.js, 修改我们的webpack配置。我们修改webpack output内的 library 和 libraryTarget 字段。

output.library: 导出的对象名
output.libraryTarget: 导出后要挂载到哪里

同时,因为我们是远程调用,还需要设置 publicPath 字段为你的真实服务地址。否则加载子chunk时,会去当前浏览器域名的根路径寻找,有404问题。
因为我们本地的服务启动是localhost:3000,所以我们就设置 //localhost:3000。

独立运行
我们的子服务现在是无法独立运行的,现在我们改造为可以独立 + 集成双模式运行
single-spa 有个属性,叫做 window.singleSpaNavigate。如果为true,代表就是single-spa模式。如果false,就可以独立渲染。
改造一下子项目的main.js :

/**** 添加这里 ****/
if (!window.singleSpaNavigate) { // 如果不是single-spa模式
  delete vueOptions.el;
  new Vue(vueOptions).$mount('#app');
}

这样,我们就可以独立访问子服务的 index.html


使用 single-spa 进行前端架构设计可以带来很多好处:
例如:
在同一页面上使用多个前端框架而不用刷新页面] (react,vue等 )
独立部署每一个单页面应用
新功能使用新框架,旧的单页应用不用重写可以共存
改善初始加载时间,延迟加载代码

缺点:

  • 在上面父项目加载子项目的代码中,我们可以看到。我们要注册一个子服务,需要一次性加载2个JS文件。如果需要加载的JS更多,甚至生产环境的 bundle 有唯一hash, 那我们还能写死文件名和列表吗?
  • 侵入性太强,不仅要在入口导出生命周期,还要更改 Webpack 配置
    JS Entry 的接入微应用方式来简陋了,我们更希望是通过一个 index.html 的 url 来接入微应用
    啥都没有,比如 JS、CSS 隔离,主微应用通信等这些都需要别的小库来解决
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容