uni-app 一个域名下部署多个应用方案解析

uni-app 一个域名下部署多个应用方案解析

一、技术背景与需求分析

在uni-app跨平台开发场景中,企业常面临多应用部署的挑战:独立域名成本高、维护复杂,而单域名多应用部署可显著降低资源消耗。典型场景包括:

  1. 企业级应用矩阵:主应用+管理后台+数据看板共用域名
  2. SaaS多租户系统:不同客户应用通过路径区分
  3. 营销活动组合:主站与多个H5活动页面共享域名

核心需求点:路径隔离、独立更新、权限控制、性能优化。技术实现需兼顾uni-app的跨端特性(H5/小程序/App)与Web服务器的路由能力。

二、核心实现方案

方案1:基于路径的子目录部署

技术原理:通过Web服务器配置将不同应用映射到域名子路径,如:

  1. https://example.com/app1 → 应用A
  2. https://example.com/app2 → 应用B

实现步骤

  1. 前端配置

    • 修改manifest.json中的H5配置:
      1. "h5": {
      2. "router": {
      3. "base": "/app1/" // 设置应用基础路径
      4. },
      5. "publicPath": "/app1/" // 静态资源路径
      6. }
    • 确保所有资源引用(JS/CSS/图片)使用相对路径或配置后的publicPath
  2. 服务器配置(Nginx示例):

    1. location /app1/ {
    2. alias /path/to/app1/dist/;
    3. try_files $uri $uri/ /app1/index.html;
    4. }
    5. location /app2/ {
    6. alias /path/to/app2/dist/;
    7. try_files $uri $uri/ /app2/index.html;
    8. }

优势:配置简单,适合独立开发的应用
挑战:需处理跨应用Cookie隔离、静态资源缓存冲突

方案2:微前端架构集成

技术原理:将uni-app作为子应用嵌入主框架,通过JS沙箱实现隔离

实现要点

  1. 主框架设计

    • 使用qiankun或single-spa等微前端库
    • 配置子应用入口:
      1. registerMicroApps([
      2. {
      3. name: 'app1',
      4. entry: '//example.com/app1/',
      5. container: '#subapp-container',
      6. activeRule: '/app1'
      7. }
      8. ]);
  2. uni-app适配

    • 修改main.js导出生命周期:
      1. export async function bootstrap() {
      2. console.log('app1 bootstrap');
      3. }
      4. export async function mount(props) {
      5. // 渲染逻辑
      6. }
      7. export async function unmount() {
      8. // 卸载逻辑
      9. }
    • 配置vue.config.js输出UMD格式:
      1. module.exports = {
      2. configureWebpack: {
      3. output: {
      4. library: `app1`,
      5. libraryTarget: 'umd'
      6. }
      7. }
      8. }

优势:动态加载、独立版本控制
挑战:增加架构复杂度,需处理样式隔离、通信机制

方案3:多页面应用(MPA)模式

技术原理:在单个uni-app项目中配置多页面入口

实现步骤

  1. 配置pages.json

    1. {
    2. "pages": [
    3. {
    4. "path": "pages/app1/index",
    5. "style": { "navigationBarTitleText": "应用A" }
    6. },
    7. {
    8. "path": "pages/app2/index",
    9. "style": { "navigationBarTitleText": "应用B" }
    10. }
    11. ],
    12. "subPackages": [
    13. {
    14. "root": "packageA",
    15. "pages": [...]
    16. }
    17. ]
    18. }
  2. 路由控制

    • 通过中间页实现路径跳转:
      1. // 在入口文件判断路径
      2. const path = window.location.pathname;
      3. if (path.startsWith('/app1')) {
      4. uni.reLaunch({ url: '/pages/app1/index' });
      5. }

优势:单项目维护,共享公共代码
局限:H5端需配合服务器重定向,小程序端受平台限制

三、关键问题解决方案

1. 静态资源路径处理

问题:子目录部署时资源404
解决方案

  • 配置vue.config.jspublicPath
    1. module.exports = {
    2. publicPath: process.env.NODE_ENV === 'production'
    3. ? `/app1/`
    4. : '/'
    5. }
  • 使用<base>标签(仅H5):
    1. <base href="/app1/">

2. 跨应用通信

场景:主应用与子应用数据交互
实现方案

  • 使用postMessage API:

    1. // 主应用发送
    2. window.parent.postMessage({
    3. type: 'APP_SWITCH',
    4. data: { target: 'app2' }
    5. }, '*');
    6. // 子应用接收
    7. window.addEventListener('message', (e) => {
    8. if (e.data.type === 'APP_SWITCH') {
    9. // 处理逻辑
    10. }
    11. });
  • 或通过全局状态管理(如Vuex)

3. 性能优化策略

实施要点

  1. 代码分割
    1. // vue.config.js
    2. module.exports = {
    3. configureWebpack: {
    4. optimization: {
    5. splitChunks: {
    6. chunks: 'all'
    7. }
    8. }
    9. }
    10. }
  2. 预加载
    1. <link rel="preload" href="/app1/js/chunk-vendors.js" as="script">
  3. 服务端缓存
    1. location /app1/ {
    2. expires 1y;
    3. add_header Cache-Control "public";
    4. }

四、部署架构示例

典型拓扑

  1. 用户请求 CDN边缘节点 Nginx负载均衡
  2. ├── 应用A容器(/app1/)
  3. ├── 应用B容器(/app2/)
  4. └── 静态资源服务

CI/CD流程

  1. 各应用独立构建:

    1. # 应用A构建
    2. UNI_APP_BASE=/app1/ npm run build:h5
    3. # 应用B构建
    4. UNI_APP_BASE=/app2/ npm run build:h5
  2. 自动部署到对应目录
  3. Nginx配置热更新

五、安全与监控

安全措施

  1. 路径验证
    1. // 中间件验证
    2. app.use((req, res, next) => {
    3. if (!/^\/(app1|app2)\//.test(req.path)) {
    4. return res.status(403).send('Forbidden');
    5. }
    6. next();
    7. });
  2. CSP策略
    1. add_header Content-Security-Policy "default-src 'self' example.com";

监控方案

  1. 应用性能监控(APM):
    1. // 集成Sentry
    2. import * as Sentry from '@sentry/browser';
    3. Sentry.init({ dsn: 'YOUR_DSN' });
  2. 日志分离:
    1. location /app1/ {
    2. access_log /var/log/nginx/app1.access.log;
    3. }

六、最佳实践建议

  1. 开发阶段

    • 使用环境变量区分部署路径
    • 建立统一的脚手架工具
  2. 测试阶段

    • 实施跨应用接口测试
    • 验证路径切换的边界情况
  3. 运维阶段

    • 制定独立的回滚方案
    • 监控各应用的资源使用

进阶方案:对于超大规模应用,可考虑:

  • 容器化部署(Docker+K8s)
  • 服务网格架构(Istio)
  • 边缘计算节点部署

通过合理选择上述方案,开发者可在uni-app框架下实现高效的多应用部署,平衡开发效率与运维成本。实际项目中,建议根据团队技术栈、应用复杂度及长期维护成本进行综合评估。