主应用就不用说了,只要搭建完毕就可以接入其它多个各式各样的子应用项目,我这里主要介绍的是子应用脚手架如何接入主应用
我这里是直接用的react官方推荐的脚手架,在这个基础上进行修改。
一,子项目搭建
安装react脚手架
npx react-create-app react-demo
输入命令暴露脚手架隐藏的配置文件
npm run eject
不出意外的情况下,应该是可以看到我们的目录出现了好几个目录,那就代表暴露成功了
二,配置修改
1. 修改config/webpackDevServer.config.js
module.exports = function (proxy, allowedHost) {
return {
headers: {
'Access-Control-Allow-Origin': '*', // 表示允许跨域
},
...
};
2.修改config/webpack.config.js
return {
...
output: {
// The build folder.
...
// 微应用配置
library: `${appPackageJson.name}-[name]`,
libraryTarget: 'umd'
},
...
};
新建 public_path.js 在main.js中引入就好了,不过我这里不知道为什么报错,给注释掉了,似乎也没有影响使用,就暂时没去关注了
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
}
3.更新main.js文件(也就是index.js文件 主路由)
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
// bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
// 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
export async function bootstrap() {
console.log('react app bootstraped');
}
// 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
export async function mount(props) {
console.log(props)
console.log('主应用传递过来的值,在这里通过 props接收')
ReactDOM.render( , props.container ? props.container.querySelector('#root') : document.getElementById('root'));
}
// 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
export async function unmount(props) {
ReactDOM.unmountComponentAtNode(props.container ? props.container.querySelector('#root') : document.getElementById('root'));
}
// 可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效
export async function update(props) {
console.log('update props', props);
}
ReactDOM.render(
,
document.getElementById('root')
);
reportWebVitals();
值得注意的是:
- bootstrap,mount,unmount 这三个生命周期是必须要有的,用于主应用识别是否合法应用。而其它的生命周期则都是可选的
- 生命周期函数必须有返回值,可以是 promise 或者 async 函数
- 如果到处都是函数数组而不是单个函数,这些函数会被依次调用,对于promise函数,会等到resolve之后再调用下一个函数
到了这里子应用的工作其实已经OK了,再去主引用按照它的规范要求,去接入就好了
三,一些小问题
按照上面的要求一步步操作,是可以接入都基座了的。但是会有一些小小bug
比如说,项目接入到主应用之后,静态资源会访问404了,这会是什么原因呢,看了下webpack的配置项发现是路径的问题
在config/webpack.config.js文件下output中有个这样的配置
publicPath: paths.publicUrlOrPath,
意思是当前地址,如果是子应用单独打开是OK的,而之所以在主应用里paths的值就发生改变了,路径不一样了。我这里暂时只找到了个比较死板的方法,那就是直接写死,把子应用部署后的路径写上去如下:
publicPath: 'http://localhost:3000/', // 这个地方是为了防止接入qiankun子应用静态资源无法渲染的情况
http://localhost:3000/ 是我本地项目子应用的目录
肯定是还有更好的办法,但是目前还没找到,哈哈哈,下回有时间再研究研究,或者有小伙伴知道可以在下面留言,如果上面哪里写的有误还请见谅,多多指教。