在vue项目上使用阿里qiankun ——项目搭建篇(一)
什么是微前端简单来说就是1、复用(嵌入)别人的项目页面,但是别人的项目运行在他自己的环境之上。2、巨无霸应用拆分成一个个的小项目,这些小项目独立开发部署,又可以自由组合进行售卖本文主要讲解如何在vue项目上使用阿里的qiankun插件进行微前端实践,对微前端的概念会在另外的文章中进行阐述,demo会附在文末。首先我准备了三个项目、分别是主应用main-app、子应用b-child、c-child。
什么是微前端
简单来说就是
1、复用(嵌入)别人的项目页面,但是别人的项目运行在他自己的环境之上。
2、巨无霸应用拆分成一个个的小项目,这些小项目独立开发部署,又可以自由组合进行售卖
本文主要讲解如何在vue项目上使用阿里的qiankun插件进行微前端实践,对微前端的概念会在另外的文章中进行阐述,demo会附在文末。
首先我准备了三个项目、分别是主应用main-app、子应用b-child、c-child。三个应用均是采用Vue技术栈,路由均是采用history模式
改造主应用main-app
1、首先需要安装qiankun框架 npm i qiankun -S
2、然后我们需要改造一下app.vue文件,我们要在app.vue中创建一个容器,负责把获取到的子应用加载到这里容器里面。
<template>
<div id="app">
<header>
<router-link to="/about">主应用的page页面</router-link>
<router-link to="/b-child">子应用B</router-link>
<router-link to="/c-child">子应用C</router-link>
<router-link to="/">回到主应用</router-link>
</header>
<router-view></router-view>
<!-- id为appContainer就是放置子应用的容器 -->
<div id="appContainer"></div>
</div>
</template>
2、在src目录下创建qiankun.js文件,引用qiankun并且封装好
import {
registerMicroApps,
start
} from 'qiankun'
export const useQiankun = () => {
const apps = [
{
name: 'b-child', // 必选,微应用的名称,微应用之间必须确保唯一
entry: 'http://localhost:8022', // - 必选,微应用的入口
container: '#appContainer', // -必选,微应用的容器节点的选择器或者 Element 实例
activeRule: '/b-child', // - 必选,微应用的激活规则
props: { // - 可选,主应用需要传递给微应用的数据。
msg: '我是父应用传过来的值,传递给B应用'
}
},
{
name: 'c-child',
entry: 'http://localhost:8033',
container: '#appContainer',
activeRule: '/c-child',
props: {
msg: '我是父应用传过来的值,传递给C应用'
}
}
]
registerMicroApps(apps, {
beforeLoad: [
app => {
console.log(`${app.name}的beforeLoad阶段`)
}
],
beforeMount: [
app => {
console.log(`${app.name}的beforeMount阶段`)
}
],
afterMount: [
app => {
console.log(`${app.name}的afterMount阶段`)
}
],
beforeUnmount: [
app => {
console.log(`${app.name}的beforeUnmount阶段`)
}
],
afterUnmount: [
app => {
console.log(`${app.name}的afterUnmount阶段`)
}
]
})
start({ experimentalStyleIsolation: true, prefetch: 'all' })
}
具体的配置项说明可以参考qiankun的官方文档
3、在main.js中引用
import {
useQiankun
} from './qiankun'
const vueApp = new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
vueApp.$nextTick(() => {
useQiankun()
})
这里为了确保装载子应用的容器已创建,我们需要在new Vue()之后,等DOM加载好了在注册并启动qiankun
改造子应用b-child
1、在src目录下新增文件public-path.js,主要用于修改子项目的publicPath
/* eslint-disable camelcase */
if (window.__POWERED_BY_QIANKUN__) {
// eslint-disable-next-line no-undef
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
}
2、在main.js,引入public-path.js 并配合主项目导出single-spa需要的三个生命周期。注意:路由实例化需要在main.js里面完成,以便于路由的销毁,所以路由文件只需要导出路由配置即可(原模板导出的是路由实例)
import './public-path'
import Vue from 'vue'
import App from './App.vue'
import routes from './router'
import VueRouter from 'vue-router'
import store from './store'
Vue.config.productionTip = false
let router = null
let instance = null
function render ({ container, parentStore } = {}) {
router = new VueRouter({
base: window.__POWERED_BY_QIANKUN__ ? '/b-child' : process.env.BASE_URL,
mode: 'history',
routes
})
instance = new Vue({
router,
store,
data () {
return {
parentStore
}
},
render: h => h(App)
}).$mount(container ? container.querySelector('#bChild') : '#bChild')
// index.html 里面的 id 需要改成 appVueHash,否则子项目无法独立运行
}
if (!window.__POWERED_BY_QIANKUN__) {
// 全局变量来判断环境
render()
}
/**
* bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
* 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
*/
export async function bootstrap () {
console.log('现在进入子应用b-child的bootstraped阶段')
}
/**
* 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
*/
export async function mount (props) {
if (props.parentStore) {
await props.parentStore.dispatch('getResource', { name: 'B应用的资源' })
}
console.log('现在进入子应用b-child的mount周期', props)
render(props)
}
/**
* 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
*/
export async function unmount () {
console.log('现在进入子应用b-child的unmount阶段')
instance.$destroy()
instance.$el.innerHTML = ''
instance = null
router = null
}
/**
* 可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效
*/
export async function update (props) {
console.log('update props', props)
}
这里有两点是需要注意的
1、修改public文件下的index.html 挂在应用的id,否则子项目无法独立运行
2、由于我们采用的是history模式,我们需要给路由设置base
base: window.__POWERED_BY_QIANKUN__ ? '/b-child' : process.env.BASE_URL
3、修改打包配置文件vue.config.js ,主要是允许跨域、以及打包成umd格式
/*
* @Author: Hzh
* @Date: 2021-04-22 18:16:41
* @LastEditTime: 2021-04-25 15:58:34
* @LastEditors: Hzh
* @Description:
*/
'use strict'
const path = require('path')
function resolve (dir) {
return path.join(__dirname, dir)
}
const port = 8022 // 端口配置
const { name } = require('./package')
module.exports = {
publicPath: process.env.NODE_ENV === 'development' ? '/' : '/b-child/',
outputDir: 'dist',
assetsDir: 'static',
lintOnSave: process.env.NODE_ENV === 'development',
productionSourceMap: false,
devServer: {
port: port,
open: false, // 启动项目以后自动打开浏览器
hot: true,
hotOnly: false,
overlay: {
warnings: false,
errors: true
},
proxy: {
'/auth': {
target: 'www.baidu.com',
changeOrigin: true,
pathRewrite: {
'^/auth': 'auth'
}
}
},
headers: {
'Access-Control-Allow-Origin': '*'
}
},
configureWebpack: {
name: name,
resolve: {
alias: {
'@': resolve('src')
}
},
output: {
// 把子应用打包成 umd 库格式
library: `${sysName}`, // 微应用的包名,这里与主应用中注册的微应用名称一致
libraryTarget: 'umd', // 将你的 library 暴露为所有的模块定义下都可运行的方式
jsonpFunction: `webpackJsonp_${sysName}`// 按需加载相关,设置为 webpackJsonp_vue-projec 即可
},
}
}
到这一步子应用就改造完成了,c-child同理改造即可。
关于qiankun微前端的实战,如何解决主应用与子应用的通讯、子应用与子应用的通讯,子应用跳转子应用,如何实现子应用的keep-alive,本系列将持续更新说明
本示例的Demo码云地址:https://gitee.com/zhihua0123/qiankun-demo

更多推荐



所有评论(0)