如何在单个Express服务中部署运行多个Vue项目
单Express服务部署多Vue应用落地方案
问题根因
你遇到的路由冲突、子应用404、静态资源加载失败,本质是三个配置错误:
- Vue子应用打包时的公共资源路径未匹配部署路径,导致资源请求打到根目录
connect-history-api-fallback默认全局生效,把子应用的请求全部回退到主应用的入口文件- Express中间件匹配顺序错误,通用规则提前拦截了子应用的专属请求
分步配置流程
1. 调整两个Vue项目的打包参数
先统一目录规范:把所有子项目(静态HTML、Vue子应用)的构建产物都放到backend/dist/project目录下,kinder子项目构建后放到backend/dist/project/kinder,和现有静态子项目的访问规则对齐,方便后续维护。
- 主Vue项目:
vue.config.js中publicPath保持默认值/- 若使用Vue Router history模式,路由初始化时设置
base: '/' - 构建产物输出到
backend/dist目录即可
- 子Vue项目(kinder):
vue.config.js中设置publicPath: '/project/kinder/',末尾斜杠不能省略,打包后所有JS、CSS、静态资源的引用路径会自动带上该前缀,不会到根目录找资源- 若使用Vue Router history模式,路由初始化时设置
base: '/project/kinder/';若使用hash模式无需修改路由配置,但publicPath必须按上述要求设置 - 构建产物输出到之前约定的
backend/dist/project/kinder目录
2. 修正Express服务配置
Express的中间件是按代码书写顺序从上到下匹配的,越具体的路径规则越要放在前面,避免被通用规则拦截。参考配置如下:
const express = require('express') const path = require('path') const history = require('connect-history-api-fallback') const app = express() // -------------------------- // 子项目规则全部放在主项目前面 // -------------------------- // 1. 挂载kinder子项目静态资源 app.use('/project/kinder', express.static(path.join(__dirname, 'dist/project/kinder'))) // 2. 给kinder子项目单独配置history回退:所有/project/kinder开头的路径,都回退到子项目自己的入口文件 app.use('/project/kinder', history({ index: '/project/kinder/index.html' })) // 3. history回退后重新挂载一次子项目静态资源,保证回退后资源能正常匹配 app.use('/project/kinder', express.static(path.join(__dirname, 'dist/project/kinder'))) // 4. 挂载其他静态HTML类子项目的静态资源 app.use('/project', express.static(path.join(__dirname, 'dist/project'))) // -------------------------- // 最后配置主项目规则 // -------------------------- // 5. 挂载主项目静态资源 app.use(express.static(path.join(__dirname, 'dist'))) // 6. 主项目history回退 app.use(history()) // 7. 回退后重新挂载主项目静态资源 app.use(express.static(path.join(__dirname, 'dist'))) // 服务启动逻辑按你原有写法即可 app.listen(你的端口号)
排查要点
- 如果配置后仍有静态资源404,打开浏览器F12网络面板看报错资源的请求路径:如果请求路径是
/js/xxx.js这类根目录路径,说明子项目publicPath未生效,修改后重新打包即可,正常的子项目资源路径应该是/project/kinder/js/xxx.js - 不要全局只注册一个history中间件,默认配置会把所有GET请求重写到根目录的index.html,子项目请求会被主应用路由直接拦截
- 如果子项目使用hash路由,可以删掉对应子项目的history相关配置,只要静态资源挂载正确、publicPath配置正确即可正常访问,hash值不会传递给服务端,不会产生路由冲突
- 后续新增其他Vue子项目时,只需要按照kinder的配置规则,新增一段对应路径的静态资源挂载+专属history回退逻辑即可,不需要修改现有配置
内容的提问来源于stack exchange,提问作者purplenaive
相关产品推荐
相关产品推荐

