前言
上篇介绍了 qiankun 主应用子应用的配置要求,这篇介绍具体的子应用的改造方法。
webpack 项目
允许跨域配置
webpack-dev-server
module.exports = {
devServer: {
headers: {
'Access-Control-Allow-Origin': '*',
},
},
}
导出生命周期
声明导出生命周期的 js 文件
webpack 的入口 js 文件在打包后就是一个 script 标签,因此满足 qiankun 从最后一个 script 标签对应的 js 文件读取生命周期的条件,因此不用再添加 entry 属性。
导出生命周期
export async function bootstrap() {
console.log('app bootstraped');
}
export async function mount(props) {
console.log("app mount");
}
export async function unmount() {
console.log("app unmount")
}
const { name } = require('./package');
module.exports = {
output: {
library: `${appName}-[name]`,
libraryTarget: 'umd',
},
}
因为 qiankun 会从 window 上的某个属性上去获取生命周期,因此为了使打包后的 bootstrap / mount / unmount 等生命周期函数可以挂到 window 的某个属性上,首先必须设置 libraryTarget 为 umd 或者 window / global / this。使其可以挂在 window 上,其次必须设置 library,否则这三个函数会被直接挂在 window 上,qiankun 无法拿到。
处理动态加载的资源路径
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
特殊配置
jsonpFunction 为 webpack 打包 import() 的资源时特有的特殊改造,如果子应用中有动态 import() 的代码,则一定要配置。jsopnFunction 在 webpack5 中被更名为 chunkLoadingGlobal。
module.exports = {
output: {
jsonpFunction: `webpackJsonp_${appName}`,//webpack4
//chunkLoadingGlobal: `webpackJsonp_${appName}`,//webpack5
},
}
非 webpack 项目
这里以普通的项目,以 http-server 起服务为例的配置。
允许跨域配置
http-server
http-server -c-1 --cors
导出生命周期
非 webpakc 的项目只需要按照 qiankun 获取生命周期函数的原理进行配置导出生命周期函数的 js 文件后,直接往 window 上挂生命周期对象就行。
声明导出生命周期的 js 文件
可以将导出生命周期的 js 文件对应的 script 标签放置最后,也可以添加 entry 属性指定。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Purehtml Example</title>
</head>
<body>
<div>
Purehtml Example
</div>
</body>
+ <script src="//yourhost/entry.js" entry></script>
</html>
导出生命周期
在 entry js 里声明 lifecycles。
const render = ($) => {
$('#purehtml-container').html('Hello, render with jQuery');
return Promise.resolve();
};
((global) => {
global['purehtml'] = {
bootstrap: () => {
console.log('purehtml bootstrap');
return Promise.resolve();
},
mount: () => {
console.log('purehtml mount');
return render($);
},
unmount: () => {
console.log('purehtml unmount');
return Promise.resolve();
},
};
})(window);
PS: 挂在 window 上的生命周期函数对象对应的属性名可以为任意值,比如上面的 purehtml
,也可以是 xxx
。但是根据 qiankun 获取生命周期函数的方式来看,最好设置为该子应用在主应用注册的 appName 最佳。否则在后面再在 window 上挂了一个属性,就会导致错误❌。
处理动态加载的资源路径
写死即可,或者发布在 cdn 上。
特殊配置
子应用全局变量
后续供其他文件全局使用的用 var 定义的全局变量和全局的 function,在 qiankun 里面,由于 eval+with 包裹执行的特征,导致本应该挂在 window 上的这些全局变量,都变成了在函数中定义了,无法自动挂在 window 上了。则需要在后面手动挂在 window 上。
var a = 123
function test(){}
// add to the end
window.a = a;
window.test = test;
mount 在前,render 声明在后
qiankun 在激活子应用的时候,会立马调用子应用的 bootstrap``mount
生命周期函数。但是有时候此时 render 函数还没出现,还没被定义,因此拿不到 render 函数放在 mount 里。
此时可以将 mount 函数进行改造如下:
setTimeout(() => {
function render(props) {
console.log('render')
}
window["waitRender"](render)
}, 5000)
;((global) => {
global['purehtml'] = {
bootstrap: () => {
console.log('purehtml bootstrap');
return Promise.resolve();
},
mount: (props) => {
console.log('purehtml mount');
new Promise((resolve, reject) => {
window["waitRender"] = resolve
}).then(fn => fn(props))
return Promise.resolve();
},
unmount: () => {
console.log('purehtml unmount');
return Promise.resolve();
},
};
})(window);