微前端之qiankun
qiankun前言bugqiankun实战前言qiankun 框架是基于single-spa框架的,所以遵循的协议都一样,也是向外暴露三个钩子函数,但是qiankun 在single-spa的基础上进行了改进:1,与技术栈无关2,解决了single-spa的隔离问题,css隔离,js隔离3,js沙箱机制4,可以预加载子应用5,主应用也无需构建请求,内部封装了fecth请求,只需要子应用配置跨域就行
qiankun
前言
qiankun 框架是基于single-spa框架的,所以遵循的协议都一样,也是向外暴露三个钩子函数,但是qiankun 在single-spa的基础上进行了改进:
1,与技术栈无关
2,解决了single-spa的隔离问题,css隔离,js隔离
3,js沙箱机制
4,可以预加载子应用
5,主应用也无需构建请求,内部封装了fecth请求,只需要子应用配置跨域就行
bug
昨天晚上开始写,不断遇见bug,解决一个又会遇见另外一个,真好。今天早上才解决完成,主要遇到的问题是react子应用上的bug,好久没用react了,版本问题,配置问题都有。
一:子应用挂载dom的问题
这次qiankun实战使用vue作为主应用,子应用有vue,react技术栈,这就出现问题了,vue作为主应用,vue也构建了子应用,都是挂载到id 为app的容器上,本来子应用应该是挂载到自己的HTML上,然后再挂载到主应用的容器上,结果出现了子应用挂载到主应用id 为app 的容器上,覆盖主应用,所以子应用应该配置与子应用不一样的挂载id
配置前:
配置后:
二:在配置好react子应用时,npm start可以运行,但是在groom浏览器就是不显示页面
报错:Cannot read property ‘forEach’ of undefined
解决:跟新groom 中react-devtools工具,版本问题
三:配置react子应用,主应用请求重定向为子应用绝对路径
报错:webpack_public_path is not defined
解决:eslint的问题
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
],
"globals": {
"__webpack_public_path__": true
}
},
qiankun实战
1,构建主应用,子应用
// 构建主应用
vue create qiankun-base
// 构建vue子应用
vue create child-vue
//构建react子应用
create-react-app child-react
2,主应用安装qiankun,这里子应用无需安装其他插件
npm i qiankun --save
3,配置路由,可以原生也可以使用UI库
npm i element-ui --save
4,配置主应用,注册子应用,在主应用中声明两个容器接收子应用
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
import { registerMicroApps, start } from 'qiankun';
registerMicroApps([
{
name: 'reactApp', //子应用的名字
entry: '//localhost:3020', // 子应用的路径
container: '#react', // 装载子应用的容器
activeRule: '/react', // 路由匹配
},
{
name: 'vueApp',
entry: '//localhost:3010',
container: '#vue',
activeRule: '/vue',
}
]);
// 启动 qiankun
start();
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount('#app')
// 乾坤主应用会根据配置项,主动发起fecth请求,加载子应用,所以配置子应用的时候,需要解决跨域
5,配置vue子应用
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false
let instance = null;
function render () {
instance = new Vue({
router,
render: h => h(App)
}).$mount('#app-vue')
}
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
export async function bootstrap() {
}
export async function mount() {
render();
}
export async function unmount() {
instance.$destroy();
}
配置vue.config.js
module.exports = {
devServer: {
headers: {
'Access-Control-Allow-Origin': '*',
},
port:3010
},
configureWebpack: {
output: {
library: `vueApp`,
libraryTarget: 'umd', // 把微应用打包成 umd 库格式
},
},
};
vue子应用中有路由,记得修改路由base
6,配置react子应用
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
// 定义一个渲染函数,方便主应用调用和子应用自己运行
function render () {
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
}
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
export async function bootstrap() {
}
export async function mount() {
// 挂载子应用
render();
}
export async function unmount() {
// 卸载子应用
ReactDOM.unmountComponentAtNode(document.getElementById('root'))
}
reportWebVitals();
创建配置文件config-overrides.js
module.exports = {
webpack: (config) => {
config.output.library = `reactApp`;
config.output.libraryTarget = 'umd';
config.output.globalObject = 'window';
config.output.publicPath = `http://localhost:3020/`
return config;
},
devServer: (configFunction) => {
return function (proxy,allowedHost){
const config = configFunction(proxy,allowedHost);
config.headers = {
"Access-Control-Allow-Origin":'*'
}
return config
}
},
}
注意修改eslint中的配置
7,分别运行主,子应用
总结
通过qiankun实现微前端,比single-spa性能更好,上手更容易。总体来说搭建一个微前端应用不是很难,不管是single-spa还是qiankun。
qiankun官网:官方文档
qiankun中的沙箱机制
什么是沙箱机制?
沙箱就是应用运行的环境,在沙箱中运行的应用,不会影响外界应用,当沙箱中的应用卸载后,主应用可以还原之前的状态。这就是为什么主应用加载微应用,显示完微应用,可以看到之前的主应用。原来主应用的js,css都被缓存起来了。
一:快照沙箱
当页面不支持Proxy,使用快照沙箱,也是代理的意思,原生只能创建一个。
二:Proxy沙箱
使用es6中的Proxy实现代理,可以支持创建多个沙箱。
更多推荐
所有评论(0)