微前端之qiankun
qiankun
- 前言
- bug
- qiankun實(shí)戰(zhàn)
- 總結(jié)
- qiankun中的沙箱機(jī)制
前言
qiankun 框架是基于single-spa框架的,所以遵循的協(xié)議都一樣,也是向外暴露三個(gè)鉤子函數(shù),但是qiankun 在single-spa的基礎(chǔ)上進(jìn)行了改進(jìn):
1,與技術(shù)棧無(wú)關(guān)
2,解決了single-spa的隔離問題,css隔離,js隔離
3,js沙箱機(jī)制
4,可以預(yù)加載子應(yīng)用
5,主應(yīng)用也無(wú)需構(gòu)建請(qǐng)求,內(nèi)部封裝了fecth請(qǐng)求,只需要子應(yīng)用配置跨域就行
bug
昨天晚上開始寫,不斷遇見bug,解決一個(gè)又會(huì)遇見另外一個(gè),真好。今天早上才解決完成,主要遇到的問題是react子應(yīng)用上的bug,好久沒用react了,版本問題,配置問題都有。
一:子應(yīng)用掛載dom的問題
這次qiankun實(shí)戰(zhàn)使用vue作為主應(yīng)用,子應(yīng)用有vue,react技術(shù)棧,這就出現(xiàn)問題了,vue作為主應(yīng)用,vue也構(gòu)建了子應(yīng)用,都是掛載到id 為app的容器上,本來(lái)子應(yīng)用應(yīng)該是掛載到自己的HTML上,然后再掛載到主應(yīng)用的容器上,結(jié)果出現(xiàn)了子應(yīng)用掛載到主應(yīng)用id 為app 的容器上,覆蓋主應(yīng)用,所以子應(yīng)用應(yīng)該配置與子應(yīng)用不一樣的掛載id
配置前:
配置后:
二:在配置好react子應(yīng)用時(shí),npm start可以運(yùn)行,但是在groom瀏覽器就是不顯示頁(yè)面
報(bào)錯(cuò):Cannot read property ‘forEach’ of undefined
解決:跟新groom 中react-devtools工具,版本問題
三:配置react子應(yīng)用,主應(yīng)用請(qǐng)求重定向?yàn)樽討?yīng)用絕對(duì)路徑
報(bào)錯(cuò):webpack_public_path is not defined
解決:eslint的問題
"eslintConfig": {"extends": ["react-app","react-app/jest"],"globals": {"__webpack_public_path__": true}},qiankun實(shí)戰(zhàn)
1,構(gòu)建主應(yīng)用,子應(yīng)用
// 構(gòu)建主應(yīng)用 vue create qiankun-base // 構(gòu)建vue子應(yīng)用 vue create child-vue //構(gòu)建react子應(yīng)用 create-react-app child-react2,主應(yīng)用安裝qiankun,這里子應(yīng)用無(wú)需安裝其他插件
npm i qiankun --save3,配置路由,可以原生也可以使用UI庫(kù)
npm i element-ui --save4,配置主應(yīng)用,注冊(cè)子應(yīng)用,在主應(yīng)用中聲明兩個(gè)容器接收子應(yīng)用
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', //子應(yīng)用的名字entry: '//localhost:3020', // 子應(yīng)用的路徑container: '#react', // 裝載子應(yīng)用的容器activeRule: '/react', // 路由匹配},{name: 'vueApp',entry: '//localhost:3010',container: '#vue',activeRule: '/vue',} ]); // 啟動(dòng) qiankun start();Vue.config.productionTip = falsenew Vue({router,render: h => h(App) }).$mount('#app')// 乾坤主應(yīng)用會(huì)根據(jù)配置項(xiàng),主動(dòng)發(fā)起fecth請(qǐng)求,加載子應(yīng)用,所以配置子應(yīng)用的時(shí)候,需要解決跨域5,配置vue子應(yīng)用
import Vue from 'vue' import App from './App.vue' import router from './router'Vue.config.productionTip = falselet 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__; }// 獨(dú)立運(yùn)行時(shí) 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', // 把微應(yīng)用打包成 umd 庫(kù)格式},}, };vue子應(yīng)用中有路由,記得修改路由base
6,配置react子應(yīng)用
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')); // 定義一個(gè)渲染函數(shù),方便主應(yīng)用調(diào)用和子應(yīng)用自己運(yùn)行 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() { // 掛載子應(yīng)用render(); }export async function unmount() {// 卸載子應(yīng)用ReactDOM.unmountComponentAtNode(document.getElementById('root')) }reportWebVitals();創(chuàng)建配置文件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,分別運(yùn)行主,子應(yīng)用
總結(jié)
通過(guò)qiankun實(shí)現(xiàn)微前端,比single-spa性能更好,上手更容易。總體來(lái)說(shuō)搭建一個(gè)微前端應(yīng)用不是很難,不管是single-spa還是qiankun。
qiankun官網(wǎng):官方文檔
qiankun中的沙箱機(jī)制
什么是沙箱機(jī)制?
沙箱就是應(yīng)用運(yùn)行的環(huán)境,在沙箱中運(yùn)行的應(yīng)用,不會(huì)影響外界應(yīng)用,當(dāng)沙箱中的應(yīng)用卸載后,主應(yīng)用可以還原之前的狀態(tài)。這就是為什么主應(yīng)用加載微應(yīng)用,顯示完微應(yīng)用,可以看到之前的主應(yīng)用。原來(lái)主應(yīng)用的js,css都被緩存起來(lái)了。
一:快照沙箱
當(dāng)頁(yè)面不支持Proxy,使用快照沙箱,也是代理的意思,原生只能創(chuàng)建一個(gè)。
二:Proxy沙箱
使用es6中的Proxy實(shí)現(xiàn)代理,可以支持創(chuàng)建多個(gè)沙箱。
總結(jié)
以上是生活随笔為你收集整理的微前端之qiankun的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微前端之single-spa
- 下一篇: 前端面试宝典(一)