微前端——乾坤qiankunDemo
微前端——qiankun(乾坤)实例
⼀、什么是微前端
微前端就是将不同的功能按照不同的维度拆分成多个⼦应⽤。通过主应⽤来加载这些⼦应⽤。微前端的核⼼在于拆,拆完后在合!
⼆、为什么使⽤微前端
1. 不同团队间开发同⼀个应⽤技术栈不同
2. 希望每个团队都可以独⽴开发,独⽴部署
3. 项⽬中还需要⽼的应⽤代码
我们可以将⼀个应⽤划分成若⼲个⼦应⽤,将⼦应⽤打包成⼀个个的 lib 。当路径切换 时加载不同的⼦应⽤。这样每个⼦应⽤都是独⽴的,技术栈也不⽤做限制了!从⽽解决了前端协同开发问题。
三、qiankun框架
**⽂档地址:**/zh
2018 年 Single-SPA 诞⽣了, single-spa 是⼀个⽤于前端微服务化的 JavaScript 前端解决⽅案 ( 本⾝没有处理样式隔离, js 执⾏隔离) 实现了路由劫持和应⽤加载。
2019 年 qiankun 基于 Single-SPA, 提供了更加开箱即⽤的 API ( single-spa + sandbox + import-html-entry ) 做到了,技术栈⽆关、并且接⼊简单(像 i frame ⼀样简单)。
四、qiankun框架实例
这⾥我们打算建⽴三个项⽬进⾏实操,⼀个Vue项⽬充当主应⽤,另⼀个Vue和React应⽤充当⼦应⽤
1、创建三个应⽤
1)创建基座
vue create qiankun-base
2)创建⼦应⽤1
vue create qiankun-vue
3)创建⼦应⽤2
cnpm install -g create-react-app
create-react-app qiankun-react
三个项⽬
基座:qiankun-base ⼦应⽤:qiankun-vue、qiankun-react
2、项⽬配置(主要)
1)基座qiankun-base配置
项⽬创建好后我们⾸先进⾏主应⽤qiankun-base的配置,进⼊man.js⽂件进⾏配置, 在main.js中加⼊以下代码,要注意的是,entry 这项配置是我们两个⼦项⽬的域名和端⼝,我们必须确保两字⼦项⽬运⾏在这两个端⼝上⾯,container就是我们的容器名,就是我们⼦应⽤挂载的节点,相当于Vue项⽬⾥⾯的app节点,activeRule就是我们的激活路径,根据路径来显⽰不同的⼦应⽤。
引⼊qiankun插件
yarn add qiankun 或者 npm i qiankun -S
main.js配置
// 引⼊qiankun
import { registerMicroApps, start } from 'qiankun';
const apps = [
{
name: 'vueApp', // 应⽤的名字
entry: '//localhost:8081', // 默认会加载这个html 解析⾥⾯的js 动态的执⾏(⼦应⽤必须⽀持跨域)fetch
container: '#vue', // 容器名(此项⽬页⾯中定义的容器id,⽤于把对应的⼦应⽤放到此容器中)
activeRule: '/vue', // 激活的路径
props: { a: 1 } // 传递的值(可选)
},
{
name: 'reactApp',
entry: '//localhost:20000', // 默认会加载这个html 解析⾥⾯的js 动态的执⾏(⼦应⽤必须⽀持跨域)fetch
container: '#react',
activeRule: '/react',
}
]
registerMicroApps(apps); // 注册应⽤
start({
prefetch: false // 取消预加载
});// 开启
配置完之后我们去到qiankun-base的app.vue⽂件进⾏主应⽤的页⾯编写,这⾥我安装了element-ui来进⾏页⾯美化npm i element-ui -S
在main.js中引⼊element-ui:
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
修改app.vue的组件代码
<template>
<div id="app">
<el-menu :router="true" mode="horizontal">
<!--基座中可以放⾃⼰的路由-->
<el-menu-item index="/">Home</el-menu-item>
<el-menu-item index="/about">About</el-menu-item>
<!--引⽤其他⼦应⽤-->
<el-menu-item index="/vue">vue应⽤</el-menu-item>
<el-menu-item index="/react">react应⽤</el-menu-item>
</el-menu>
<router-view></router-view>
<div id="vue"></div>
<div id="react"></div>
</div>
</template>
router.js代码
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')    }
]
const router = new VueRouter({
mode: 'history',
// base: v.BASE_URL,
base: '',
routes
})
export default router
2)⼦应⽤qiankun-vue配置
main.js配置
import App from './App.vue'
import router from './router'
// fig.productionTip = false
let instance = null
function render(props) {
instance = new Vue({
router,
render: h => h(App)
}).$mount('#qkApp'); // 这⾥是挂载到⾃⼰的html中基座会拿到这个挂载后的html 将其插⼊进去}
if (window.__POWERED_BY_QIANKUN__) { // 动态添加publicPath
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
if (!window.__POWERED_BY_QIANKUN__) { // 默认独⽴运⾏
render();
}
// ⽗应⽤加载⼦应⽤,⼦应⽤必须暴露三个接⼝:bootstrap、mount、unmount
// ⼦组件的协议就ok了
export async function bootstrap(props) {
};
export async function mount(props) {
render(props)
}
export async function unmount(props) {
instance.$destroy();
}
router.js配置
为什么使用bootstrap?import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]
const router = new VueRouter({
mode: 'history',
base: '/vue',
routes
})
export default router
在⼦应⽤的根⽬录下⾯新建⼀个fig.js⽂件
lintOnSave: false,  // 关闭eslint检测
devServer: {
port: 8080,//这⾥的端⼝是必须和⽗应⽤配置的⼦应⽤端⼝⼀致
headers: {
//因为qiankun内部请求都是fetch来请求资源,所以⼦应⽤必须允许跨域
'Access-Control-Allow-Origin': '*'
}
},
configureWebpack: {
output: {
/
/资源打包路径
library: 'vueApp',
libraryTarget: 'umd'
}
}
}
3)⼦应⽤qiankun-react配置
src⽬录下index.js⽂件
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
function render(){
<React.StrictMode>
<App />
</React.StrictMode>,
);
}
if(!window.__POWERED_BY_QIANKUN__){
render();
}
export async function bootstrap(){
}
export async function mount() {
render()
}
export async function unmount(){
ReactDOM.unmountComponentAtNode( ElementById('root'));  // 卸载节点}
config-overrides.js配置
先引⼊react-app-rewired,在修改package.json启动命令
npm install react-app-rewired
修改package.json启动命令

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。