51CTO首页
AI.x社区
博客
学堂
精品班
直播训练营
企业培训
鸿蒙开发者社区
WOT技术大会
AIGC创新中国行
公众号矩阵
移动端

基于 Qiankun 微前端实践- 从零到一篇

开发 前端
微前端就是将不同的功能按照不同的维度拆分成多个子应用。通过主应用来加载这些子应用。微前端的核心在于拆,拆完后再合!

简短的概括:微前端痛点与解决问题

1、使用背景

1)在同一个页面可以使用多个前端框架(React, AngularJS, Vue 等);

2)用新框架编写新代码,无需重写已有的 app;

3)代码的延迟加载可以缩减初次加载时长;

2、主要解决的问题:

1)在一个 app 中不同的模块由不同的团队维护,而每个团队所用的技术栈可能不同,而且发版周期不同。

2)所使用的前端框架升级负担,新版本可能存在不兼容的更新,升级后可能对已有的业务产生 bug,造成难以升级。限制了前端框架新版本的使用。

一、为什么需要微前端

「~ 微前端导图 ~」

我们通过 3w (what,why,how) 的方式来讲解微前端

1、what? 什么是微前端?

微前端就是将不同的功能按照不同的维度拆分成多个子应用。通过主应用来加载这些子应用。

微前端的核心在于拆,拆完后再合!

微前端架构具备以下几个核心价值:(重要)(摘自 qiankun官方文档)

1)技术栈无关

主框架不限制接入应用的技术栈,微应用具备完全自主权;

2)独立开发、独立部署

微应用仓库独立,前后端可独立开发,部署完成后主框架自动完成同步更新;

3)增量升级

在面对各种复杂场景时,我们通常很难对一个已经存在的系统做全量的技术栈升级或重构,而微前端是一种非常好的实施渐进式重构的手段和策略;

4)独立运行时

每个微应用之间状态隔离,运行时状态不共享;

2、why? 为什么去使用他?

1)不同团队间开发同一个应用技术栈不同怎么破?

2)希望每个团队都可以独立开发,独立部署怎么破?

3)项目中还需要老的应用代码怎么破?

我们是不是可以将一个应用划分成若干个子应用,将子应用打包成一个个的lib。当路径切换时加载不同的子应用。这样每个子应用都是独立的,技术栈也不用做限制了!从而解决了前端协同开发问题。

3、How? 怎么落地微前端?

2018年 Single-SPA 诞生了,single-spa 是一个用于前端微服务化的 JavaScript 前端解决方案(本身没有处理样式隔离,js 执行隔离)实现了路由劫持和应用加载。

说明:single-spa 解决了以应用为维度的路由,应用的注册,监听,最重要的是赋予了应用生命周期和生命周期相关事件。

*Single-SPA 缺陷:不够灵活,不能动态加载js文件;样式不隔离,没有js沙箱的机制。

2019年 qiankun 是微前端框架,提供了更加开箱即用的 API (single-spa + sandbox + import-html-entry),它基于 single-spa,具备 js 沙箱、样式隔离、HTML Loader、预加载 等微前端系统所需的能力。qiakun 升级 2.0 后,支持多个微应用的同时加载,有了这个特性,我们基本可以像接入 iframe 一样方便的接入微应用。

*总结:子应用可以独立构建,运行时动态加载,主子应用完全解耦,技术栈无关,靠的是协议接入(子应用必须导出 bootstrap,mount,unmount方法)

扩展:

1)Single-SPA 官网地址:

https://zh-hans.single-spa.js.org/docs/getting-started-overview

2)qiankun官网地址:

https://qiankun.umijs.org/zh

二、解决隔离的方案

1、css 隔离方案

子应用之间样式隔离:

Dynamic Stylesheet 动态样式表,当应用切换时移除老应用样式,添加新应用样式;

主应用和子应用之间的样式隔离:

1)BEM(Block Element Modifier ) 约定项目前缀;

2)css-Modules 打包时生成不冲突的选择器名;

3)Shadow DOM 真正意义上的隔离;

4)css-in-js

2、沙箱 shaowDom

*css 解决方法:

// domapi
// 外界无法访问 shadow dom
let shadowDOM = document.getElementById('x').attachShadow({mode: 'closed'});
let pElm = document.createElement('p');
pElm.innerHTML = 'hello';
let styleElm = document.createElement('style');
styleElm.textContent = `
p{color: red}
`
shadowDOM.appendchild(styleElm);
shadowDOM.appendchild(pElm);

*JS 沙箱 proxy

快照沙箱简单理解:1年前拍一张 在拍一张 (将区别保存起来) 在回到一年前

源码实践

let sandbox = new SnapshotSandbox();

class SnapshotSandbox{
constructor(){
this.proxy = window; // window属性
this.modifyPropsmap = {}; // 记录在window上的修改
this.active();
}
active() { // 激活
this.windowSnapshot = {}; //拍照
for(const prop in window) {
if(window.hasOwnProperty(prop)){
this.windowsnapshot[prop] = window[prop];
}
}
object.keys(this.modifyPropsMap).forEach(p=>{
window[p] = this.modifyPropsMap[p];
})
}

inactive(){ // 失活
for(const prop in window){
if(window.hasOwnProperty(prop)){
if(window[prop] !== this.windowsnapshot[prop]){
this.modifyPropsMap[prop] = window[prop];
window[prop] = this.windowsnapshot[prop]
}
}
}
}
}

// 应用的运行 从开始到结束, 切换后不会影响全局
((window)=> {
window.a = 1;
window.b = 2;
console.log(window.a,window.b);
sandbox.inactive();
console.log(window.a,window.b);
sandbox.active();
console.log(window.a,window.b);
})(sandbox.proxy); // sandbox.proxy 就是window
// 如果是多个子应用就不能使用这种方式了,es6proxy
// 代理沙箱可以实现多应用沙箱。把不同的应用用不同的代理来处理

三、qiankun (乾坤) 项目实践

*将普通的项目改造成 qiankun 主应用基座,需要进行三步操作:

1、创建微应用容器 - 用于承载微应用,渲染显示微应用

2、注册微应用 - 设置微应用激活条件,微应用地址等等;

3、启动 qiankun;

扩展:主应用不限技术栈,只需要提供一个容器 DOM,然后注册微应用并 start 即可。

*微前端 qiankun 项目实践:主应用(基座)配置 react 17.0.2,子应用配置 vue 2.6.10

详细配置如下:

1. 主应用(基座)配置 react 17.0.2

1.1 主应用为子应用准备的 展示元素 (文件:src/App.js )

import {BrowserRouter as Router,Link} from 'react-router-dom'
function App() {
return (
<div className="App">
<Router>
<Link to="/vue">vue应用</Link>
</Router>
{/* 切换导航, 将微应用渲染container容器中 */}

<div id="container"></div>
</div>
);
}

export default App;

1.2 引入react 渲染,注册 registerApps (文件:src/index.js )

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './registerApps'

ReactDOM.render(
<App />,
document.getElementById('root')
);

1.3 在主应用中注册微应用(文件:src/registerApps.js)

1、安装 qiankun (建议安装:qiankun 2.X以上,支持多个微应用的同时加载)

yarn add qiankun 或者 npm i qiankun

相关配置信息:

// ------ Step1 引入 qiankun
import { registerMicroApps, start } from 'qiankun'; // 底层是基于single-spa

// ----- Step2 注册子应用
registerMicroApps([{
name: 'm-vue',
entry: '//localhost:20000',
container: '#container',
activeRule: '/vue',
},
], {
beforeLoad: () => {
console.log('加载前')
},
beforeMount: () => {
console.log('挂在前')
},
afterMount: () => {
console.log('挂载后')
},
beforeUnmount: () => {
console.log('销毁前')
},
afterUnmount: () => {
console.log('销毁后')
},
})

// ----- Step3 启动应用
start();

2. 子应用配置 vue 2.6.10

主应用基座只有一个主页,现在我们需要接入微应用。

qiankun 内部通过 import-entry-html 加载微应用,要求微应用需要导出生命周期钩子函数(见下图)。

从上图可以看出,qiankun 内部会校验微应用的生命周期钩子函数,如果微应用没有导出这三个生命周期钩子函数,则微应用会加载失败。

如果我们使用了脚手架搭建微应用的话,我们可以通过 webpack 配置在入口文件处导出这三个生命周期钩子函数。如果没有使用脚手架的话,也可以直接在微应用的 window 上挂载这三个生命周期钩子函数。

2.1 调整子应用 main.js 文件:

import Vue from 'vue'
import App from './App.vue'
import router from './router'

// Vue.config.productionTip = false

let instance = null
function render(props) {
instance = new Vue({
router,
render: h => h(App)
}).$mount('#app'); // 这里是挂载到自己的html中 基座会拿到这个挂载后的html 将其插入进去
}

if (window.__POWERED_BY_QIANKUN__) { // 动态添加publicPath
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
if (!window.__POWERED_BY_QIANKUN__) { // 默认独立运行
render();
}

// 需要暴露接入协议
export async function bootstrap(props) {
console.log('[vue] vue app bootstraped');
};
export async function mount(props) {
console.log('[vue] props from main framework', props);
render(props);
}
export async function unmount(props) {
instance.$destroy();
instance.$el.innerHTML = '';
instance = null;
router = null;
}

说明:导出相应的生命周期钩子函数。

微应用需要在自己的入口 js (通常就是你配置的 webpack 的 entry js) 导出 bootstrap、mount、unmount 三个生命周期钩子,以供主应用在适当的时机调用。

*扩展资源:

/**
* bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
* 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
*/
export async function bootstrap() {
console.log('[vue] vue app bootstraped');
}

/**
* (重要)应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
*/
export async function mount(props) {
console.log('[vue] props from main framework', props);
storeTest(props);
render(props);
}

/**
* 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
*/
export async function unmount() {
instance.$destroy();
instance.$el.innerHTML = '';
instance = null;
router = null;
}

/**
* 可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效
*/
export async function update(props) {
console.log('update props', props);
}

2.2 新建 vue.config.js,配置如下

module.exports = {
devServer:{
port:10000,
headers:{
// 解决跨域
'Access-Control-Allow-Origin':'*'
}
},
configureWebpack:{
output:{
// 把子应用打包成 umd 库格式
library: `${name}-[name]`,
libraryTarget: 'umd',
jsonpFunction: `webpackJsonp_${name}`,
}
}
}

*基于 qiankun 微前端项目 (实践代码库)

https://github.com/jiasx/mic-front-vue2.0

https://github.com/jiasx/mic-front-react

责任编辑:姜华 来源: 前端学苑
相关推荐
前端qiankun项目实践
qiankun是一个基于singlespa的微前端实现库,旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。

2020-05-06 09:25:10

微前端 qiankun 架构
基于前端qiankun的多页签缓存方案实践
本文梳理了基于阿里开源微前端框架qiankun,实现多页签及子应用缓存的方案,同时还类比了多个不同方案之间的区别及优劣势,为使用微前端进行多页签开发的同学,提供一些参考。

2022-07-27 22:56:45

前端 应用缓存 qiankun
WorkManager入门实践,有这一篇就够了
一般情况下,我们大部分的操作都是在app打开的时候进行的,但是在某些情况下,即使app关闭了,我们也可能需要执行必要的动作,或者会采取一个动作,而不是让用户等待加载,我们可以在后台执行此操作并通知用户结果。

2021-11-24 22:42:15

WorkManager API
SQLMongoDB,这一篇就够了
对于SQL转战NoSQL的开发人员来说,最难的一步其实是将原有的SQL的概念和知识直接复用过来,最大化的减小学习的成本。

2020-03-09 17:28:51

NoSQL MongoDB 数据库
SringMVC入门源码,这一篇就够
Java行业的谁人不知SSM框架呢除非你告诉我刚学Java,我就相信你不知道SpringMVC。

2020-09-10 06:56:12

SringMVC 源码 参数
Nginx入门干活,看这一篇足矣
Nginx(enginex)是一款轻量级的Web服务器、反向代理服务器及电子邮件(IMAPPOP3)代理服务器。

2021-01-14 07:15:19

Nginx Web 服务器
一篇让我们学会React实践
每天都在写业务代码中度过,但是呢,经常在写业务代码的时候,会感觉自己写的某些代码有点别扭,但是又不知道是哪里别扭,今天这篇文章我整理了一些在项目中使用的一些小的技巧点。

2021-07-29 07:55:20

React 实践 代码
一篇带给你 webpack 优秀实践
本文讲述的最佳实践是从日常业务中总结而出的,不一定适合所有项目。毕竟每个公司或个人的项目不同,最佳实践也会有所不同。但是可以从这篇文章借鉴吸收一点有用的东西。

2021-07-08 07:30:13

Webpack 前端 Tree shakin
一篇学会 PageRank 算法与实践
PageRank通过网络浩瀚的超链接关系来确定一个页面的等级。Google把从A页面到B页面的链接解释为A页面给B页面投票,Google根据投票来源(甚至来源的来源,即链接到A页面的页面)和投票目标的等级来决定新的等级。

2022-03-04 08:17:53

PageRank 网络 等级
前端登录,这一篇就够了
登录是每个网站中都经常用到的一个功能,在页面上我们输入账号密码,敲一下回车键,就登录了,但这背后的登录原理你是否清楚呢?今天我们就来介绍几种常用的登录方式。

2020-08-03 10:00:11

前端 登录 服务器
前端:, 轻松把自己的网站部署服务器
有许多选项可用于使用PM2管理我们的应用程序。目前H5Dooring也是采用这种方式部署的,所以如果你有自己的网站,赶紧参考这个教程部署吧

2021-08-07 21:51:17

服务器 网站 部署
前端,轻松把自己的网站部署服务器
今天我们来分享点轻松且有用的知识.作为一名前端工程师,没有个自己的网站怎么行,接下来我就来带大家介绍一下如何从零到一,配置并部署自己的网站到服务器.

2023-01-12 22:00:48

解读Rollup Plugin
rollup的插件本质是一个处理函数,返回一个对象。返回的对象包含一些属性(如name),和不同阶段的钩子函数(构建build和输出output阶段),以实现插件内部的功能.

2021-10-28 07:10:21

rollup Plugin 插件编写
一篇带给你 Jenkins Pipeline as Code 实践
今天我们就一起来探讨一下pipelineascode。

2022-09-20 07:33:15

Jenkins https://mp
前端实战:实现H5拼图小游戏
我去年曾写过一个用H5,Javascript,css3实现的拼拼乐小游戏,技术栈采用自己封装的类Jquery框架Xuery,其中涉及到了很多经典的javascript算法和css3特性,对大家的编程能力会有很大的提高,文末我也会放上源码获取方式,大家可以学习体验一下。

2021-08-15 22:52:30

前端 H5 拼图
技术运营中台建设到AIOps实践,看着一篇就够了
5G商用启动开始,三大运营商正式推出了5G套餐,5G是下一代通信技术,那么5G时代来了之后同样需要下一代运维。

2020-01-08 09:44:59

运维 架构 技术
一篇带你从开始学微服务
虽然现在开源的微服务框架有很多,各种编程语言的都有,花上几个小时搭建一套可运行的开发环境也并不是一件难事。但毕竟微服务涉及的组件还是挺多的,相比于单体架构来说,复杂度提升了不少。

2023-02-20 09:55:00

微服务框架 单体架构
Kubernetes 集群网络懵圈熟悉,看这一篇就够了
在Kubernetes中要保证容器之间网络互通,网络至关重要。

2021-04-14 15:54:20

Kubernetes 程序 工具
TypeScript ,2020 开发必备
从弱类型到强类型,开发更加严谨,是前端发展的必然趋势。TypeScript作为JS的超集,自然也推动着前端开发人员去学习TS,特别是Vue3出现之后且大部分第三方库都有TS编译文件之后。TS的掌握就渐渐变成一项基础技能。

2020-09-08 18:37:49

TypeScript 开发 前端

代做工资流水公司福州企业对公流水代开威海转账流水图片株洲薪资银行流水代开西宁背调流水代做德阳转账流水代开德阳办房贷银行流水无锡离职证明宜春签证流水办理赣州代办薪资流水沧州代办工资流水app截图南京代办离职证明武汉自存流水代做舟山代办流水兰州打在职证明济宁制作房贷银行流水临沂工资流水单制作九江代开流水单宜春签证银行流水 多少钱南京贷款银行流水打印合肥开个人工资流水嘉兴房贷流水图片新乡银行流水账代办常德办银行流水上饶公司银行流水图片南通代做企业对私流水武汉查薪资银行流水阜阳房贷工资流水 代办南昌制作工资流水铜陵银行流水代开徐州在职证明报价香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声卫健委通报少年有偿捐血浆16次猝死汪小菲曝离婚始末何赛飞追着代拍打雅江山火三名扑火人员牺牲系谣言男子被猫抓伤后确诊“猫抓病”周杰伦一审败诉网易中国拥有亿元资产的家庭达13.3万户315晚会后胖东来又人满为患了高校汽车撞人致3死16伤 司机系学生张家界的山上“长”满了韩国人?张立群任西安交通大学校长手机成瘾是影响睡眠质量重要因素网友洛杉矶偶遇贾玲“重生之我在北大当嫡校长”单亲妈妈陷入热恋 14岁儿子报警倪萍分享减重40斤方法杨倩无缘巴黎奥运考生莫言也上北大硕士复试名单了许家印被限制高消费奥巴马现身唐宁街 黑色着装引猜测专访95后高颜值猪保姆男孩8年未见母亲被告知被遗忘七年后宇文玥被薅头发捞上岸郑州一火锅店爆改成麻辣烫店西双版纳热带植物园回应蜉蝣大爆发沉迷短剧的人就像掉进了杀猪盘当地回应沈阳致3死车祸车主疑毒驾开除党籍5年后 原水城县长再被查凯特王妃现身!外出购物视频曝光初中生遭15人围殴自卫刺伤3人判无罪事业单位女子向同事水杯投不明物质男子被流浪猫绊倒 投喂者赔24万外国人感慨凌晨的中国很安全路边卖淀粉肠阿姨主动出示声明书胖东来员工每周单休无小长假王树国卸任西安交大校长 师生送别小米汽车超级工厂正式揭幕黑马情侣提车了妈妈回应孩子在校撞护栏坠楼校方回应护栏损坏小学生课间坠楼房客欠租失踪 房东直发愁专家建议不必谈骨泥色变老人退休金被冒领16年 金额超20万西藏招商引资投资者子女可当地高考特朗普无法缴纳4.54亿美元罚金浙江一高校内汽车冲撞行人 多人受伤

代做工资流水公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化