uni-app 一个域名下部署多个应用

一、背景与需求分析

在uni-app开发场景中,企业或开发者常面临多应用部署需求:例如同一品牌下的小程序端、H5端、App端需共享域名资源,或不同业务模块(如用户端、管理端)需独立部署但共用基础设施。传统方案需为每个应用单独配置域名,导致DNS管理复杂、SSL证书成本增加、SEO优化分散等问题。而通过”一个域名下部署多个应用”,可实现资源复用、统一访问入口、降低运维成本,尤其适合中大型项目的微前端架构或跨平台统一部署场景。

二、技术实现方案

1. 基于路由的前端分离方案

原理:通过URL路径区分不同应用,例如https://domain.com/app1https://domain.com/app2
实现步骤

  • uni-app路由配置:在pages.json中设置基础路径,例如:
    1. {
    2. "pages": [
    3. {
    4. "path": "app1/pages/index/index",
    5. "style": { "navigationBarTitleText": "应用1" }
    6. },
    7. {
    8. "path": "app2/pages/index/index",
    9. "style": { "navigationBarTitleText": "应用2" }
    10. }
    11. ],
    12. "subPackages": [
    13. {
    14. "root": "app1",
    15. "pages": [...]
    16. },
    17. {
    18. "root": "app2",
    19. "pages": [...]
    20. }
    21. ]
    22. }
  • Nginx配置:通过location指令匹配路径并转发请求:

    1. server {
    2. listen 80;
    3. server_name domain.com;
    4. location /app1 {
    5. alias /path/to/app1/dist;
    6. try_files $uri $uri/ /app1/index.html;
    7. }
    8. location /app2 {
    9. alias /path/to/app2/dist;
    10. try_files $uri $uri/ /app2/index.html;
    11. }
    12. }

    优势:无需后端支持,纯前端实现,适合静态资源部署。
    局限:需确保路径不冲突,且H5端需处理历史模式路由兼容性。

2. 基于子目录的动态加载方案

适用场景:需动态切换应用或共享公共资源时。
实现步骤

  • 构建配置:在vue.config.js中设置publicPath
    1. module.exports = {
    2. publicPath: process.env.NODE_ENV === 'production' ? '/app1/' : '/'
    3. };
  • 动态加载逻辑:通过JavaScript检测URL路径并加载对应应用:
    1. const appPath = window.location.pathname.split('/')[1];
    2. if (appPath === 'app1') {
    3. import('./app1/main.js').then(module => {
    4. module.default();
    5. });
    6. } else if (appPath === 'app2') {
    7. import('./app2/main.js').then(module => {
    8. module.default();
    9. });
    10. }

    优化点:使用webpackSplitChunksPlugin拆分公共依赖,减少重复加载。

3. 基于反向代理的后端路由方案

原理:通过Nginx或Apache将不同路径代理至不同后端服务。
配置示例(Nginx):

  1. location /app1 {
  2. proxy_pass http://backend-app1;
  3. proxy_set_header Host $host;
  4. }
  5. location /app2 {
  6. proxy_pass http://backend-app2;
  7. proxy_set_header Host $host;
  8. }

优势:支持动态API路由,适合需要后端渲染的场景。
注意:需确保后端服务能正确处理Host头和路径前缀。

三、关键问题与解决方案

1. 跨域问题

现象:不同子应用间API请求可能触发CORS错误。
解决方案

  • Nginx统一配置:在server块中添加:
    1. add_header 'Access-Control-Allow-Origin' '*';
    2. add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
  • 前端代理:开发环境配置devServer.proxy
    1. devServer: {
    2. proxy: {
    3. '/app1/api': { target: 'http://backend-app1' },
    4. '/app2/api': { target: 'http://backend-app2' }
    5. }
    6. }

2. 静态资源路径

问题:子目录部署时,CSS/JS路径可能错误。
解决

  • 构建时指定publicPath为相对路径(如./)。
  • 使用<base>标签动态设置基础路径:
    1. <base href="/app1/">

3. 状态管理隔离

需求:不同应用需独立存储状态(如Vuex)。
方案

  • 为每个应用创建独立的Vuex实例:
    ```javascript
    // app1/store.js
    export default new Vuex.Store({…});

// app2/store.js
export default new Vuex.Store({…});

  1. - 动态挂载Store
  2. ```javascript
  3. const appPath = getAppPath();
  4. const store = require(`./${appPath}/store.js`).default;
  5. new Vue({ store, ... }).$mount('#app');

四、性能优化建议

  1. 资源合并:使用webpackSplitChunksPlugin拆分公共库(如Vue、uni-app核心)。
  2. 预加载:通过<link rel="preload">提前加载关键资源。
  3. CDN加速:将公共静态资源(如字体、图片)托管至CDN。
  4. 服务端渲染(SSR):对首屏性能要求高的应用,可结合Nuxt.js或uni-app的SSR方案。

五、安全与运维

  1. HTTPS统一配置:使用Let’s Encrypt免费证书为域名配置SSL。
  2. 访问控制:通过Nginx的auth_basic或后端API鉴权限制敏感路径。
  3. 日志监控:统一记录各应用的访问日志,便于问题排查。
  4. 自动化部署:使用Jenkins或GitLab CI实现多应用同步构建与发布。

六、案例与最佳实践

案例1:某电商平台将用户端(H5/小程序)部署在/m路径,管理端部署在/admin路径,通过Nginx反向代理至不同后端服务,实现资源隔离与权限控制。
案例2:某企业将内部多个uni-app工具应用部署在/tools/app1/tools/app2等路径,共享登录态与用户数据。
最佳实践

  • 路径设计遵循RESTful风格,如/app/{version}/{module}
  • 统一错误处理机制,避免路径错误导致白屏。
  • 定期清理无用子应用,避免路径冲突。

七、总结与展望

通过路由分离、子目录部署、反向代理等技术,uni-app可高效实现一个域名下部署多个应用,显著降低运维成本。未来,随着微前端架构的普及,基于uni-app的多应用部署将进一步向自动化、容器化方向发展,建议开发者关注Serverless、边缘计算等新兴技术对部署模式的变革。