qiankun前端微应用项目使用说明
1、使用原因项目越来越大,运行打包较慢(主要)。目前的前端项目使用vue架构,页面已经超过了100张,打包越来越慢,虽然已经进行了压缩处理,但是修改一个地方,重新编译全部,电脑有点带不动了。多种业务逻辑混杂在一个系统,有时候只需要修改某个业务模块的代码,但是却要运行全部功能模块才能进行修改。2、qiankun特点https://qiankun.umijs.org/zh/guide技术栈无关,前端的
1、使用原因
-
项目越来越大,运行打包较慢(主要)。目前的前端项目使用vue架构,页面已经超过了100张,打包越来越慢,虽然已经进行了压缩处理,但是修改一个地方,重新编译全部,电脑有点带不动了。
-
多种业务逻辑混杂在一个系统,有时候只需要修改某个业务模块的代码,但是却要运行全部功能模块才能进行修改。
2、qiankun 特点https://qiankun.umijs.org/zh/guide
-
技术栈无关,前端的代码框架没有限制
-
独立开发,独立部署。升级可以只针对某个微服务进行升级
主要参考文档
https://blog.csdn.net/qq_33396780/article/details/110694871
https://blog.csdn.net/u013655559/article/details/107527135
我的理解是前端微服务具有一个主服务,多个微服务,类似于后端的微服务架构。
在我的项目中dmp_web是主服务,dmp_ai是微服务。
主服务修改配置
(1)主服务先安装qiankun插件
npm i qiankun -S
(2)主服务的页面入口App.vue
<div id="app">
<router-view />
<!-- 微服务挂载dom -->
<div id="appContainer" />
</div>
(3)主服务main.js配置
// 引入qiankun微服务,注册ai模块
import { registerMicroApps, start, initGlobalState } from 'qiankun'
// 用了getActiveRule来完成匹配,getActiveRule函数通过传入当前 location 作为参数,然后根据函数返回数值来看,若返回值为 true 时则表明当前子应用会被激活,则去调用entry入口配置
const getActiveRule = (hash) => (location) => location.hash.startsWith(hash)
const propData = {
store: store,
router: router
}
let testData = {
opt: ''
}
const actions = initGlobalState(testData)
// 主项目项目监听和修改(在项目中任何需要监听的地方进行监听)
actions.onGlobalStateChange((state, prev) => {
// state: 变更后的状态; prev 变更前的状态
console.log('改变前的值 ', prev)
console.log('改变后的值 ', state)
})
// 将actions对象绑到Vue原型上,为了项目中其他地方使用方便
Vue.prototype.$actions = actions
// 微服务模块
const apps = [
{
name: 'dmp_ai', // AI模块 应用名字
entry: process.env.NODE_ENV === 'production' ? '/dmp_ai/' : '//localhost:8890', // 入口
container: '#appContainer', // 容器名(此项目页面中定义的容器id,用于把对应的子应用放到此容器中)
activeRule: getActiveRule('#/dmp_ai/'), // 激活的路径
props: propData // 传参
}
]
registerMicroApps(apps) // 注册应用
start({
prefetch: false // 取消预加载
}) // 开启
微服务配置修改
(1)微服务main.js修改
// qiankun配置
let instance = null
function render(props) {
instance = new Vue({
router,
store, // 子应用自己的store
data() {
return {
parentStore: props && props.store ? props.store : null, // qianKun模式下,主服务的store传给子服务
parentRouter: props && props.router ? props.router : [] // qiankun模式下启动时,把主服务的路由传给子服务
}
},
render: h => h(App)
}).$mount('#devApp') // 这里是挂载到自己的html中 基座会拿到这个挂载后的html 将其插入进去
}
if (window.__POWERED_BY_QIANKUN__) { // 动态添加publicPath
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
router.beforeEach((to, from, next) => {
if (!to.path.includes('/dmp_ai')) {
next({
path: '/dmp_ai/' + to.path // 请求的路径如果是qiankun模式下动态的增加前缀dmp_ai前缀
})
} else {
next()
}
})
}
if (!window.__POWERED_BY_QIANKUN__) { // 默认独立运行
render()
}
// 父应用加载子应用,子应用必须暴露三个接口:bootstrap、mount、unmount
// 子组件的协议就ok了
export async function bootstrap(props) {
}
export async function mount(props) {
// 加了true之后,会自动调取前面这个回调方法,这样可以拿到主应用(基座)修改的值
props.onGlobalStateChange((state, prev) => {
// state: 变更后的状态; prev 变更前的状态
console.log(state, prev)
}, true)
Vue.prototype.$onGlobalStateChange = props.onGlobalStateChange
Vue.prototype.$setGlobalState = props.setGlobalState
console.log(props)
const username = props.store.getters.username
const btn_permission = props.store.getters.permissions
// 把用户名称赋值给ai服务的store,用于鉴权
store.commit('user/SET_NAME', username)
// 把按钮权限设置给ai服务的store
store.commit('user/SET_PERMISSION', btn_permission)
render(props)
}
export async function unmount(props) {
console.log('销毁子服务=================》')
instance.$destroy()
}
(2)微服务vue.config.js修改
// 打包用
publicPath: process.env.NODE_ENV === 'production' ? '/dmp_ai/' : '/',
devServer: {
port: 8090,//这里的端口是必须和父应用配置的子应用端口一致
headers: {
// 因为qiankun内部请求都是fetch来请求资源,所以子应用必须允许跨域。基座 https://dev.portal.com/ 获子应用a的资源 https://dev.monitor.com/a的资源 ,根据浏览器同源策略(浏览器采用同源策略,禁止页面加载或执行与自身来源不同的域的任何脚本)
'Access-Control-Allow-Origin': '*'
},
},
configureWebpack: {
name: name,
output: {
//资源打包路径
library: 'vueApp',
libraryTarget: 'umd'}
}
(3)微服务路由修改route.js
let prefix = '/'
// 如果是通过主服务过来的,有前缀dmp_ai
if (window.__POWERED_BY_QIANKUN__) {
prefix = '/dmp_ai/'
}
主服务,微服务的路由都是hash模式
官网说:主应用和微应用都是 hash 模式,主应用根据 hash 来判断微应用,则不用考虑这个问题。
页面跳转:
主应用跳转微应用
this.$router.push({ path: '/dmp_ai/xx' })
实际上hash模式跳转的时候,找不到dmp_ai开头的任何配置,所以会转404,所以在生成路由的时候,修改动态路由生产规则里的404配置,除了dmp_ai外的所有页面再转404
accessedRoutes.push({ path: '^dmp_ai.*', id: '99999', redirect: '/404', hidden: true })
微应用跳转主应用
this.$root.parentRouter.push('/portal')
更多推荐
所有评论(0)