何为乾坤
In Chinese,
qian(乾)means heaven andkun(坤)earth.qiankunis the universe.
用作者的话说,它是一个宇宙
这是一个vue的基础项目(vue2.0 + webpack)
这是一个react的基础项目
qiankun所做的就是把,这两个项目整一起,且流畅(iframe一点都不流畅)
上手
安装 (这里父应用添加就行)
$ yarn add qiankun # 或者 npm i qiankun -S
1.接入方式:
1.1:根据路由匹配加载
入口js配置,这里对应vue文件的main.js
import { registerMicroApps, start } from 'qiankun'
const getActiveRule = (hash) => (location) => location.hash.startsWith(hash)
registerMicroApps([
{
name: 'react app', // app name registered
entry: '//localhost:3001',
container: '#react_app',
// 这里路由用的hash模式
activeRule: getActiveRule('#/qiankunChild'),
}
]
)
start()
在app.vue中增加子应用容器
<template>
<div id="app">
<img src="./assets/logo.png">
<div id="react_app"></div>
<router-view/>
</div>
</template>
地址栏输入vue项目的端口,增加匹配后的地址qiankunChild
成功加载
1.2:手动加载
import { loadMicroApp } from 'qiankun';
loadMicroApp({
name: 'app',
entry: '//localhost:3001',
container: '#qiankunChild',
});
html部分
<h2 @click="showChild">接入 react app</h2>
<div class="child-content" id="qiankunChild"></div>
js部分
showChild () {
loadMicroApp({
name: 'app',
entry: '//localhost:3001',
container: '#qiankunChild'
})
}
点击后(这里直接在html元素下方增加的子应用)
好像成了,又好像没成,这里图片为啥没显示出来,F12一下瞅瞅
可以看到这个svg图的路径是父应用的 然而父应用没有这张图
这是什么原因呢 查看官方demo这里直接用了base64
照着来一遍,使用base64替换原导入方案
这样就ok了
2.微应用改造
通过主应用简单的安装后,子应用已经可以接入,但是只是简单的显示,后续还需要对子应用进行改造
未改造前:
主应用打开f12会提示(需要在app的入口导出生命周期)
2.1改造第一步:微应用增加生命周期
这里需要在微应用的入口js增加导出bootstrap、mount、unmount三个生命周期函数,(update为可选生命周期) 供主应用在必要时调用,这里直接在react根目录下index.js中添加
/**
* bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
* 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
*/
export async function bootstrap() {
console.log('react app bootstraped')
}
/**
* 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
*/
export async function mount(props) {
console.log('mount')
// ReactDOM.render(<App />, props.container ? props.container.querySelector('#root') : document.getElementById('root'))
}
/**
* 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
*/
export async function unmount(props) {
console.log('unmount')
// ReactDOM.unmountComponentAtNode(
// props.container ? props.container.querySelector('#root') : document.getElementById('root'),
// )
}
/**
* 可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效
*/
export async function update(props) {
console.log('from parent app', props)
}
在每个周期加点log
2.2改造第二步,修改打包配置
(这里针对react 17应用,其他项目官方文档有说明)
step1:
在 src 目录新增 public-path.js:
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
step3:
安装插件 @rescripts/cli
npm i -D @rescripts/cli
step3:
根目录新增 .rescriptsrc.js:
const { name } = require('./package');
module.exports = {
webpack: (config) => {
config.output.library = `${name}-[name]`;
config.output.libraryTarget = 'umd';
// 这里好像版本不匹配,注释
//config.output.jsonpFunction = `webpackJsonp_${name}`;
config.output.globalObject = 'window';
return config;
},
devServer: (_) => {
const config = _;
config.headers = {
'Access-Control-Allow-Origin': '*',
};
config.historyApiFallback = true;
config.hot = false;
// 这里好像版本不匹配,注释
//config.watchContentBase = false;
config.liveReload = false;
return config;
},
};
qiankun与微前端
主应用引入qiankun并且改造微应用后,即可正常使用qiankun
这边记录几个微应用比较关心的问题
1.子父应用如何通信
方式1:localStorage、window
传统方式,不做解释
方式2:使用postmessage
传统方式,不做解释
方式3:父应用手动加载子应用
父传子
调用子应用生命周期的update方法
showChild () {
this.micriAppInstance = loadMicroApp({
name: 'app',
entry: '//localhost:3001',
container: '#qiankunChild'
})
},
postValue () {
this.micriAppInstance.update({'message': 'hellow'})
}
控制台可以看到父应用向子应用传的参数,调用了之前暴露的update方法。
子传父
初始化应用时使用props增加回调函数传参
- props -
object- 可选,初始化时需要传递给微应用的数据。
父应用传参
this.micriAppInstance = loadMicroApp({
name: 'app',
entry: '//localhost:3001',
container: '#qiankunChild',
// 增加子应用回调函数
props: {
childCallback: (message) =>{
console.log(message)
}
}
})
子应用处理,这里mount生命周期可以获取到父应用传来的回调方法
export async function mount(props) {
props.childCallback && props.childCallback({'message': 'hellow , big app'})
}
可以将childCallback,绑定到子应用全局上,这样所有页面都可以调用
2.如何预加载资源
prefetchApps,见官方文档
3.样式隔离
sandbox,文档中搜索
写在最后
本文仅针对vue和react项目对qiankun进行初体验,更多内容请戳官方文档 qiankun.umijs.org/zh