跳到主要内容

部署场景:Nginx统一托管

场景:子应用不独立起服务,全部挂在同一个 nginx 下

很多公司不想给每个子应用单独起一个 node/nginx 服务。更省事的做法是:主应用和所有子应用的构建产物都是纯静态文件,统一放在一台 nginx 的站点目录下,通过 URL 路径(前缀)区分,用 try_files 解决 history 路由刷新 404

目录结构

服务器上按"一个应用一个目录"放静态产物:

/var/www/
├── main/ # 主应用构建产物
│ └── index.html
├── sub-vue/ # 子应用 vue 构建产物
│ └── index.html
└── sub-react/ # 子应用 react 构建产物
└── index.html

nginx 配置

server {
listen 80;
server_name your.domain.com;

# 主应用(根路径)
root /var/www/main;
index index.html;

# 子应用 vue,挂在 /vue 前缀下
location /vue/ {
alias /var/www/sub-vue/;
try_files $uri $uri/ /vue/index.html;
}

# 子应用 react,挂在 /react 前缀下
location /react/ {
alias /var/www/sub-react/;
try_files $uri $uri/ /react/index.html;
}

# 主应用 history 路由兜底(放最后)
location / {
try_files $uri $uri/ /index.html;
}
}

try_files $uri $uri/ /vue/index.html 是核心:用户刷新 /vue/orders 时,nginx 先找真实文件(找不到)→ 找目录(也找不到)→ 回退到 /vue/index.html,由子应用前端路由接管渲染。

配套要改的三处配置(容易漏)

1. 子应用路由 base = 挂在主应用的路径前缀

// 子应用 vue 的 router(vue-router)
base: window.__POWERED_BY_QIANKUN__ ? '/vue' : '/',

不设 base,刷新 /vue/orders 时子应用路由会认为自己在 /orders,页面空白或 404。

2. 子应用构建 publicPath = 路径前缀

资源(JS/CSS)必须按前缀产出,否则在 /vue 页面里引用的 /static/js/xxx.js 会 404:

// vue.config.js 或 webpack output
publicPath: process.env.NODE_ENV === 'production' ? '/vue/' : '/',

3. 主应用 entry 指向静态路径

registerMicroApps([
{
name: 'sub-vue',
entry: '/vue/index.html', // 或 '/vue/',同源相对路径即可
container: '#subapp-viewport',
activeRule: '/vue',
},
]);

常见问题

问题原因解法
子应用页面刷新 404子应用没配 base,或 nginx 没回退路由 base='/vue' + try_files ... /vue/index.html
子应用 JS/CSS 404publicPath 没带前缀构建设 publicPath='/vue/'
子应用里图片/字体 404资源相对路径同样走 publicPath;或子应用统一用绝对前缀路径
alias 下 try_files 回退不对alias 的回退 URI 规则易踩坑回退路径带完整前缀(/vue/index.html);仍不行就改用 root + 调整目录
主应用刷新 404主应用自己没兜底主应用 location / { try_files ... /index.html }

提示:这里的"挂同一台 nginx"既可以是同一台机器,也可以是同一个 CDN / 对象存储——只要主应用和子应用在同源下通过前缀区分,entry 就能用相对路径,也不用处理跨域。子应用之间各自独立构建、独立上传,发版互不影响。