技术栈:vue3、typescript、qiankun(阿里的微前端框架)、vue-cli4
PS: 一开始打算用
vite2
,但是调研后发现绝大多少微前端解决方案(包括qiankun
)打包策略都是基于webpack
的,vite2基本上除了官方文档,没有什么实战文章,更别说微前端的解决方案了(vite2这个工具不像vue-cli4
,已经完全抛弃了webpack)。
最近正在设计微前端项目,发现qiankun的官方文档只有vue2.x的写法,没有vue3.x的,刚好把踩完坑的demo分享出来
目录
这里我会把主应用和微应用的目录贴出来,方便大家更直观清晰的理解后面的文件引入关系
PS: 我已经删掉了不涉及微前端功能的目录,看上去更简洁
主应用
parent
├── package.json
└── src
├── App.vue
├── main.ts
├── modules
│ ├── apps.ts
│ └── index.ts
├── router
│ └── index.ts
└── views
├── About.vue
└── Home.vue
微应用
children
├── package.json
├── vue.config.js
└── src
├── App.vue
├── main.ts
├── public-path.ts
├── router
│ └── index.ts
└── views
├── About.vue
└── Home.vue
构建主应用
安装qiankun
yarn add qiankun
或者
npm i qiankun -S
创建modules
在src目录下新建modules目录,modules目录
主要用于存放qiankun
模块的相关代码
在modules目录下新建apps.ts文件
apps.ts文件用于统一存放微应用的信息
// src/modules/apps.ts
const apps: any[] = [
{
name: 'children',
entry: '//localhost:10001',
container: '#frame',
activeRule: '/children',
},
];
export default apps;
在modules目录下新建index.ts
index.ts目录用于配置、注册主应用及微应用
// src/modules/index.ts
import {
registerMicroApps,
addGlobalUncaughtErrorHandler,
start,
} from 'qiankun';
// 微应用的信息
import apps from './apps';
/**
* 注册微应用
* 第一个参数 - 微应用的注册信息
* 第二个参数 - 全局生命周期钩子
*/
registerMicroApps(apps, {
// qiankun 生命周期钩子 - 微应用加载前
beforeLoad: (app: any) => {
// 加载微应用前,加载进度条
console.log('before load', app.name);
return Promise.resolve();
},
// qiankun 生命周期钩子 - 微应用挂载后
afterMount: (app: any) => {
// 加载微应用前,进度条加载完成
console.log('after mount', app.name);
return Promise.resolve();
},
});
/**
* 添加全局的未捕获异常处理器
*/
addGlobalUncaughtErrorHandler((event: Event | string) => {
console.error(event);
});
// 导出 qiankun 的启动函数
export default start;
改动main.ts
将modules中的index.ts引入到main.ts中,并执行start
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import start from './modules';
const app = createApp(App);
start();
app
.use(store)
.use(router)
.mount('#app');
App.vue
注意,modules/apps
中的此处的微应用信息中,有个字段是container
,是用于设定微应用挂载节点的,要注意与下方<div id="frame"></div>
中的id保持一致(当然,你也可以根据自己需求自己写)
<template>
<div id="app">
<router-view>
<div id="frame"></div>
</router-view>
</div>
</template>
至此,主应用的项目代码已经修改完毕。
构建微应用
新增public-path.ts
在 src
目录下新增 public-path.ts
:
// src/public-path.ts
if ((window as any).__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = (window as any).__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
改写main.ts
本次主应用、微应用用的vue-router皆为4.0版本,与之前的3.x存在一定的差异
因qiankun是根据路由进行匹配微应用的,因此最好给微应用的路由配置加上
base: /微应用名称/
,而在vue-router@4
中的写法则为createWebHistory('/微应用名称/')
,
import { createApp } from 'vue'
import { createRouter, createWebHistory } from 'vue-router'
import App from './App.vue'
import { routes } from './router'
import store from './store'
import './public-path';
const APP_NAME = require('../package.json').name;
const app = createApp(App);
let router = null;
function render(props: any) {
const { container } = props;
router = createRouter({
history: createWebHistory(`/${APP_NAME}/`),
routes
})
app.use(store)
.use(router)
.mount(container ? container.querySelector('#app') : '#app')
}
// 独立运行时
if (!(window as any).__POWERED_BY_QIANKUN__) {
render({});
}
/**
* bootstrap : 在微应用初始化的时候调用一次,之后的生命周期里不再调用
*/
export async function bootstrap() {
console.log('bootstrap');
}
/**
* mount : 在应用每次进入时调用
*/
export async function mount(props: any) {
console.log('mount', props);
render(props);
}
/**
* unmount :应用每次 切出/卸载 均会调用
*/
export async function unmount() {
console.log('unmount');
app.unmount();
}
vue.config.js
const APP_NAME = require('./package.json').name;
const path = require("path");
module.exports = {
devServer: {
// 监听端口
port: 10001,
// 关闭主机检查,使微应用可以被 fetch
disableHostCheck: true,
// 配置跨域请求头,解决开发环境的跨域问题
headers: {
"Access-Control-Allow-Origin": "*",
},
},
configureWebpack: {
resolve: {
alias: {
"@": path.resolve(__dirname, "src"),
},
},
output: {
// 微应用的包名,这里与主应用中注册的微应用名称一致
library: APP_NAME,
// 将你的 library 暴露为所有的模块定义下都可运行的方式
libraryTarget: "umd",
// 按需加载相关,设置为 webpackJsonp_微应用名称 即可
jsonpFunction: `webpackJsonp_${APP_NAME}`,
},
},
};
package.json
{
"name": "children"
}
至此微应用的代码部分也改造完成
运行
在主应用、微应用的目录下,均运行yarn serve
启动项目
此时打开主应用的地址 localhost:8080
在看到能正常显示后,将地址改为localhost:8080/children
即可看到微应用被加载进来
结尾
这次分享的内容仅仅是在vue3的版本下如何快速上手qiankun框架, 更细致或更深入的内容建议查阅文档。 如果关于这篇分享有什么疑问的话,可以在下面的评论区告诉我哦,我会尽量解答的(大概吧🙈)
更新
- 2021/07/10
- 将文章中的
微应用
的名称均统一为children
, 涉及主应用的modules/apps
、微应用的package.json、微应用的main.ts
里的路由base: /微应用名称/
,避免出现无法正确加载的问题(因为demo被我改过多版,导致在敲文章的时候有的地方写了children,有的写了child,直接copy我代码的话可能会出现加载不到对应资源的情况, 怪我怪我😭)
- 将文章中的