qiankun微前端采坑记录
项目使用qiankun
微前端结构,遇到一些坑,记录一下。
项目说明
- 主项目:localhost:8000,主项目后端:localhost:3000,umi+qiankun
- 子项目1:localhoust:8001,子项目1后端:localhost:3001,vue+qiankun
- 子项目2:localhoust:8002,子项目2后端:localhost:3002,react+qiankun
主项目与子项目分别按照qiankun
官网接入。
主项目umi配置(.umirc.js)
routes: [
{ path: '/', component: '@/pages/index' },
{ path: '/login', component: '@/pages/login' },
{
path: '/subApp1',
microApp: 'subApp1', // 与下面的子应用对应
},
{
path: '/subApp2',
microApp: 'subApp2', // 与下面的子应用对应
},
],
qiankun: {
master: {
// 注册子应用信息
apps: [
{
name: 'subApp1', // 唯一 id,与子项目的 output.library 配对
entry: '//localhost:8001/subApp1', // html entry
},
{
name: 'subApp2', // 唯一 id,与子项目的 output.library 配对
entry: '//localhost:8002/', // html entry
},
],
},
},
主应用: <Link to="/subApp1">subApp1</Link>
,点击后路由变成:http://localhost:8000/subApp1
,此时去到子应用subApp1
,而子应用又有一个入口//localhost:8001/subApp1
,为了路由对得上,子应用需要router
有个base
为subApp1
。
- 思考1:入口改为
//localhost:8001
行不行,会出现什么问题?(答案是不行,路由跳转会出现问题,本来想回到子应用的根路径/
,结果跑到了主应用的根路径/
) - 思考2,入口改为
//localhost:8001/<otherName>
(代表别的名字),行不行?如果行,其他地方要怎么修改?
遇到的问题
- 子项目静态资源请求不正确,全部请求到主应用上,而主应用没有该资源,导致资源不存在。
eg: http://localhost:8001/img/xx.png
是有效路径,但是到了微前端里面,成了http://localhost:8000/img/xx.png
,主项目当然没有子项目的资源,界面显示图片碎裂。
- 子项目ajax请求路径不正确,全部请求到主应用上,而主应用没有子应用对应的后端proxy,导致请求无响应。
eg: http://localhost:8001/api/login
是有效请求,会自动转发到子项目的后端,但是到了微前端里面,成了http://localhost:8000/api/login
,主项目当然没有这样的请求,请求失败。
解决
http://localhost:8000/img/xx.png
改造成http://localhost:8000/subApp1/img/xx.png
,然后通过proxy
转发到http://localhost:8001/img/xx.png
http://localhost:8000/api/login
改造成http://localhost:8000/subApp1/api/login
,然后通过proxy
转发到http://localhost:8001/subApp1/api/login
单独项目运行
微前端项目运行
如上图所示,就是需要在主应用再一次proxy
代理,转发到子应用上。
主应用(umi配置):
import { defineConfig } from 'umi';
export default defineConfig({
nodeModulesTransform: {
type: 'none',
},
routes: [
{ path: '/', component: '@/pages/index' },
{ path: '/login', component: '@/pages/login' },
{
path: '/subApp1',
microApp: 'subApp1', // 与下面的子应用对应
},
{
path: '/subApp2',
microApp: 'subApp2', // 与下面的子应用对应
},
],
qiankun: {
master: {
// 注册子应用信息
apps: [
{
name: 'subApp1', // 唯一 id,与子项目的 output.library 配对
entry: '//localhost:8001/subApp1', // html entry 【1】
},
{
name: 'subApp2', // 唯一 id,与子项目的 output.library 配对
entry: '//localhost:8080/subApp2', // html entry
},
],
},
},
proxy: {
'/subApp1': { // 【2】
target: 'http://localhost:8001', // 不能写成'//localhost:8001',一定要加上'http'
changeOrigin: true,
},
'/subApp2': {
target: 'http://localhost:8002', // 不能写成'//localhost:8002',一定要加上'http'
changeOrigin: true,
},
},
});
这样,主项目中针对子项目的都会请求自动转发到对应的子项目上。当然也需要子项目相应地配合,看上面的配置中的【1】【2】,分别需要处理。
- 【1】,是指默认路由就进入有特定子项目标识的路由,好区分是哪个应用。eg: "//localhost:8001/subApp1',这样需要子应用的
router
配置一个base
,比如vue-router配置:
const router = new VueRouter({
mode: 'history',
base: 'subApp1', // 这里
routes
})
这样配置后,主项目进入子项目就去的是默认的路由,与子项目独立运行界面一致。 另外,打包配置也需要修改(vue.config.js):
module.exports = {
publicPath: '/subApp1
}
这样资源路径就会默认有 /subApp1
前缀,这样主应用转发后就能回到子应用的静态资源!
- 【2】,同意响应地,
api
请求也需要加上特有的/subApp1
前缀,加好后的配置(vue.config.js)如下:
devServer: {
headers: {
'Access-Control-Allow-Origin': '*'
},
proxy: {
- '^/api': {
+ '^/subApp1/api': {
target: 'http://localhost:3000',
changeOrigin: true,
pathRewrite: {
- '/api': '/'
+ '/subApp1/api': '/'
}
}
}
}
相应地,在api
请求时,都需要加上/subApp1
,如果你使用的是fetch
或者axios
,我相信这个操作难不倒你。
【ps】: 虽然上面只写出了vue子项目的配置,但是react也差不多。
【ps】:上面的subApp1
,subApp2
是写demo
临时取得,真实项目里面最好取个能代表子项目项目且唯一的名字,不然被嘲讽不能怪我。
完结
到此就完结了,希望对大家有帮助。
【ps】:上线的话,把对应的proxy
换成nginx
配置即可!
后续打算继续研究父子通信问题,以及多个应用相同组件库多次加载问题。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!