umi配置qiankun 微前端记录
风中勁草 2021-08-04 Umiqiankun微前端
原来使用 jquery 的项目重构,正好拆分模块,使用 umi 加 qiankun 进行重构
# umi 以及 qiankun 的使用方法
# 1. 先搭建 umi 项目,这里就不概述了,详情请访问官网umi
# 2. 安装 umi 集成的 qiankun 插件 @umijs/plugin-qianku
yarn add @umijs/plugin-qiankun -D
# 3. 使用官方推荐的路由绑定方式
载入应用地址在 config 或者 umirc.(js/ts)下设置
// config.xx.ts
export default {
qiankun: {
master: {
// 注册子应用信息
apps: [
{
name: 'app1', // 唯一 id
entry: '//localhost:7001', // html entry
},
{
name: 'app2', // 唯一 id
entry: '//localhost:7002', // html entry
},
],
},
},
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 路由配置
// router.ts
export default {
routes: [
{
path: '/',
component: '../layouts/index.js',
routes: [
{
path: '/app1',
component: './app1/index.js',
routes: [
{
path: '/app1/user',
component: './app1/user/index.js',
},
+ // 配置微应用 app1 关联的路由
+ {
+ path: '/app1/project',
+ microApp: 'app1',
+ },
],
},
+ // 配置 app2 关联的路由
+ {
+ path: '/app2',
+ microApp: 'app2'
+ },
{
path: '/',
component: './index.js',
},
],
},
],
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 这样子应用就可以通过主应用的路由进行访问了
# 4. 父子应用通讯
// src/app.ts
export function useQiankunStateForSlave() {
const [masterState, setMasterState] = useState({});
return {
masterState,
setMasterState,
};
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
官方说了如何在路由绑定的模式下如何进行父组件向着子组件传递
import { useModel } from 'umi';
function MyPage() {
const masterProps = useModel('@@qiankunStateFromMaster');
return <div>{JSON.stringify(masterProps)}</div>;
}
1
2
3
4
5
6
2
3
4
5
6
这里有一个问题,并没有说父组件如何改变自身的属性,也就是没有告知如何在父组件修改masterState
这里其实原理一样只不过要将'@@qiankunStateFromMaster'
改为'@@qiankunStateForSlave'
import { useModel } from 'umi';
function MyPage() {
const masterProps = useModel('@@qiankunStateFromSlave');
return <div>{JSON.stringify(masterProps)}</div>;
}
1
2
3
4
5
6
2
3
4
5
6
# 5. 项目打包配置
首先子应用要将 css、font、img 资源打包,这里举个例子,其他资源也是一样的
import { defineConfig } from 'umi';
export default defineConfig({
...
chainWebpack(config) {
config.module.rule('TTF').test(/.TTF$/).use('file-loader').loader('file-loader');
const imgRule = config.module.rule('images');
imgRule.uses.clear();
imgRule
.test(/\.(png|jpe?g|gif|webp|svg)(\?.*)?$/)
.use('url-loader')
.loader('url-loader')
.options({
limit: 4096, // 小于4kb将会被打包成 base64
fallback: {
loader: 'file-loader',
options: {
name: 'img/[name].[hash:8].[ext]',
publicPath: this.publicPath,
},
},
});
},
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 其次是子应用的公共前缀
export default {
define: {
// 全局变量
},
publicPath: '/micro/',
targets: {
ie: 11,
},
};
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# nginx 配置
server{
# 主应用地址里填写这个server的域名以及端口这里我只随便写的一个(root后需要跟一个斜杠)
listen 8001;
location / {
root /usr/share/nginx/html/microApp/;
try_files $uri $uri/ /index.html;
index index.html index.htm;
autoindex on;
}
}
server {
listen 80;
# 这里一定要和 公共前缀配置的publicPath一样(micro后面不需要斜杠)
location /micro {
proxy_pass http://127.0.0.1:8001/;
ssi on;
ssi_types text/shtml;
ssi_value_length 512;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 6. 其他问题
# 关于子应用动态加载路径错误
在开启dynamicImport按需加载配置时,由于@umijs/plugin-qianku
插件会自动在运行时添加runtimePublicPath因此需要在子应用的配置文件里进行关闭
// config.ts
export default defineConfig({
...
runtimePublicPath: false,
...
});
1
2
3
4
5
6
7
2
3
4
5
6
7
总结一下,首先子应用需要在配置中先配置好publicPath
这个属性,其次是对于资源文件使用file-loader
和url-loader
保证路径不会出错,如果需要开启按需加载,择需要手动关闭runtimePublicPath
。以上情况是指在本地部署时才需要做的配置。
# 关于在非本地部署时的配置
通常可以将项目生成的文件上传至OSS通过CDN访问,这样做的好处,首先通过CDN可以增加访问速度,远端服务器容灾会比部署在本地要好得多。其次免去了配置前缀的问题,由于配置前缀需要nginx,umi的配置文件互相配合,如果忽略了某一处,容易导致项目无法顺利运行。 可以使用webpack-alioss-plugin上传,配置起来比较简单。这里需要注意通知运维人员开启oss的跨域请求。