写在前面
在做大数据商业化项目时,项目比较多,使用的是iframe嵌套方式。使用上没有问题,在使用体验上可以说很难受,弹框遮罩,复制url链接时,定位不到页面等等吧,所以重构使用了qiankun,以下是使用体验,大家多多指点
1.使用
安装
npm i qiankun -S
父应用里使用,注册子应用
import { registerMicroApps, start } from 'qiankun';
registerMicroApps([
{
name: 'react-app',
entry: '//localhost:3000',
container: '#react-app',
activeRule: '/react-app',
},
{
name: 'vue-app',
entry: '//localhost:8080',
container: '#vue-app',
activeRule: '/vue-app'
},
]);
start();
子应用导出相应勾子
/**
* bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
* 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
*/
export async function bootstrap() {
console.log('react app bootstraped');
}
/**
* 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
*/
let instance
export async function mount(props) {
// react
ReactDOM.render(<App />, props.container ? props.container.querySelector('#root') : document.getElementById('root'));
// vue
instance = new Vue({
router,
store,
render: h => h(App),
})
instance.$mount(container ? container.querySelector('#app') : '#app');
}
/**
* 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
*/
export async function unmount(props) {
// react
ReactDOM.unmountComponentAtNode(
props.container ? props.container.querySelector('#root') : document.getElementById('root'),
);
// vue
instance.$destroy();
instance.$el.innerHTML = '';
instance = null;
router = null
}
/**
* 可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效
*/
export async function update(props) {
console.log('update props', props);
}
webpack 配置
publicPath: VUE_APP_NAME ? `/${VUE_APP_NAME}` : '/',
configureWebpack: config => {
return {
output: {
library: VUE_APP_NAME,
libraryTarget: 'umd',// 把微应用打包成 umd 库格式
jsonpFunction: `webpackJsonp_${VUE_APP_NAME}`,
}
}
}
此时项目就可以跑起来调试了
遇到的问题
css样式冲突问题
解决办法: 可以在每个子应用加个唯一的命名空间,忽略掉常用的组件样式
css: {
loaderOptions: {
postcss: {
plugins: [
// 自己写的插件
require('postcss-namespace')(`.${VUE_APP_NAME}`, {
// 忽略掉 element-ui 的样式,body,html, *
ignore: [/^.el\-/, 'body', 'html', '*'],
}),
],
},
},
}
主应用svg样式 影响到子应用
区分href id
菜单高亮问题
比如路由 /app/list /app/detail 从列表进入到详情时,菜单高亮无问题,但是留在详情时,刷新页面会不显示高亮菜单
子应用资源加载路径问题
当publicPath 配置没问题也会导致一些资源加载有问题, 比如,element-ui 加载的一些字体图标文件,或者css里引入了一些相对路径文件,将这些资源转为绝对路径
chainWebpack: config => {
// 字体图标路径
config.module
.rule("fonts")
.test(/\.(woff2?|eot|ttf|otf)(\?.*)?$/)
.use("url-loader")
.loader("url-loader")
.options({
limit: 0,
name: 'static/fonts/[name].[chunkhash:8].[ext]',
publicPath: process.env.NODE_ENV === 'production' ? `/${VUE_APP_NAME}` : '',
});
// 图片的相对路径改为绝对路径
config.module
.rule("images")
.test(/\.(png|jpe?g|gif|webp|ico)(\?.*)?$/)
.use("url-loader")
.loader("url-loader")
.options({
limit: 0,
// name 代表 url-loader 会将资源写到 static/fonts/ 下
name: 'static/img/[name].[chunkhash:8].[ext]',
// publicPath 代表资源引入 url 会生成 /agilebi 的前缀,比如 /VUE_APP_NAME/static/img/bg_header.790a94f4.png
publicPath: process.env.NODE_ENV === 'production' ? `/${VUE_APP_NAME}` : '',
});
}