logo

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

作者:宇宙中心我曹县2025.10.31 10:59浏览量:5

简介:本文详细阐述在uni-app框架下如何通过技术手段实现一个域名部署多个应用,重点解析路由配置、子目录部署、安全隔离等核心方案,提供从开发到运维的全流程操作指南。

一、技术背景与需求分析

1.1 为什么需要单域名多应用部署?

在uni-app开发场景中,企业常面临以下需求:

  • 资源整合:将多个关联应用(如管理后台、用户端、H5活动页)统一部署以降低运维成本
  • SEO优化:避免因多域名导致的权重分散问题
  • 合规要求:满足某些行业对备案域名数量的限制
  • 用户体验:保持品牌域名一致性,避免用户混淆

1.2 传统方案的局限性

常规部署方式存在以下痛点:

  • 独立域名模式:需申请多个备案,增加时间和经济成本
  • 子域名模式:虽可共享主域名,但需配置DNS解析和SSL证书,管理复杂度高
  • iframe嵌入:存在SEO障碍和跨域安全问题

二、核心实现方案

2.1 基于路由的路径区分方案

2.1.1 前端路由配置

在uni-app项目的pages.json中,通过路径前缀实现应用隔离:

  1. {
  2. "pages": [
  3. // 应用A(用户端)
  4. {
  5. "path": "appA/pages/index/index",
  6. "style": { "navigationBarTitleText": "应用A" }
  7. },
  8. // 应用B(管理端)
  9. {
  10. "path": "appB/pages/dashboard/index",
  11. "style": { "navigationBarTitleText": "应用B" }
  12. }
  13. ]
  14. }

2.1.2 服务器路由配置(Nginx示例)

  1. server {
  2. listen 80;
  3. server_name example.com;
  4. # 应用A路由
  5. location /appA {
  6. alias /var/www/uni-app/dist/build/appA;
  7. try_files $uri $uri/ /appA/index.html;
  8. }
  9. # 应用B路由
  10. location /appB {
  11. alias /var/www/uni-app/dist/build/appB;
  12. try_files $uri $uri/ /appB/index.html;
  13. }
  14. }

2.2 基于子目录的部署方案

2.2.1 构建配置调整

vue.config.js中设置publicPath

  1. module.exports = {
  2. publicPath: process.env.NODE_ENV === 'production'
  3. ? '/appA/' // 应用A配置
  4. : '/'
  5. }

2.2.2 静态资源处理

需确保所有资源路径包含子目录前缀:

  1. <!-- 正确写法 -->
  2. <img src="/appA/static/logo.png">
  3. <!-- 错误写法(会导致404) -->
  4. <img src="/static/logo.png">

2.3 动态应用加载方案

2.3.1 主应用入口配置

  1. // main.js
  2. const appMap = {
  3. '/appA': () => import('./appA/main.js'),
  4. '/appB': () => import('./appB/main.js')
  5. }
  6. const path = window.location.pathname
  7. for (const [prefix, loader] of Object.entries(appMap)) {
  8. if (path.startsWith(prefix)) {
  9. loader().then(module => {
  10. module.run()
  11. })
  12. break
  13. }
  14. }

2.3.2 微前端架构设计

采用模块联邦(Module Federation)实现:

  1. // webpack.config.js
  2. new ModuleFederationPlugin({
  3. name: 'appA_host',
  4. remotes: {
  5. appB: 'appB@http://example.com/appB/remoteEntry.js'
  6. }
  7. })

三、关键技术要点

3.1 跨域问题处理

3.1.1 CORS配置示例

  1. location /api {
  2. add_header 'Access-Control-Allow-Origin' '*';
  3. add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
  4. proxy_pass http://backend-server;
  5. }

3.1.2 uni-app跨域请求

  1. // manifest.json配置
  2. "h5": {
  3. "devServer": {
  4. "proxy": {
  5. "/api": {
  6. "target": "http://example.com",
  7. "changeOrigin": true
  8. }
  9. }
  10. }
  11. }

3.2 会话管理方案

3.2.1 多应用Session隔离

  1. // 应用A的登录逻辑
  2. uni.setStorageSync('appA_token', 'xxx')
  3. // 应用B的验证逻辑
  4. const token = uni.getStorageSync('appB_token')
  5. if (!token) {
  6. uni.redirectTo({ url: '/appB/pages/login' })
  7. }

3.2.2 JWT方案实现

  1. // 生成带应用标识的token
  2. const token = jwt.sign({
  3. appId: 'appA',
  4. userId: '123'
  5. }, 'secret', { expiresIn: '1h' })
  6. // 验证时解析
  7. const decoded = jwt.verify(token, 'secret')
  8. if (decoded.appId !== currentAppId) {
  9. throw new Error('Invalid app context')
  10. }

四、部署与运维实践

4.1 CI/CD流水线配置

4.1.1 GitLab CI示例

  1. build_appA:
  2. stage: build
  3. script:
  4. - cd appA
  5. - npm install
  6. - npm run build
  7. - mv dist ../public/appA
  8. build_appB:
  9. stage: build
  10. script:
  11. - cd appB
  12. - npm install
  13. - npm run build
  14. - mv dist ../public/appB

4.2 监控与日志方案

4.2.1 应用级日志隔离

  1. location /appA/logs {
  2. access_log /var/log/nginx/appA_access.log;
  3. error_log /var/log/nginx/appA_error.log;
  4. }

4.2.2 性能监控配置

  1. // 应用A的监控初始化
  2. if (process.env.APP_ID === 'appA') {
  3. const sentry = new Sentry.Init({
  4. dsn: 'https://xxx@sentry.io/123',
  5. environment: 'production'
  6. })
  7. }

五、安全加固建议

5.1 路径访问控制

  1. # 禁止直接访问应用目录
  2. location ^~ /appA/ {
  3. internal;
  4. }

5.2 输入验证机制

  1. // 路由参数验证
  2. const routes = {
  3. '/appA/user/:id': {
  4. validate: (id) => /^\d+$/.test(id),
  5. handler: loadUserPage
  6. }
  7. }

5.3 定期安全审计

建议每月执行:

  1. 依赖库漏洞扫描(npm audit
  2. SSL证书有效期检查
  3. 访问日志异常分析

六、典型应用场景

6.1 SaaS平台多租户部署

  • 每个租户对应独立子路径
  • 共享基础框架代码
  • 动态加载租户专属组件

6.2 混合APP内嵌H5应用

  • 主APP作为容器
  • 通过webview加载不同子应用
  • 统一使用原生导航栏

6.3 营销活动矩阵

  • 主域名承载长期应用
  • /promo/前缀承载短期活动
  • 自动过期清理机制

七、常见问题解决方案

7.1 路由冲突问题

现象:不同应用的同名页面路由冲突
解决方案

  1. 统一命名规范(如appA_home
  2. 使用路由守卫进行前缀校验
    1. router.beforeEach((to, from, next) => {
    2. if (!to.path.startsWith(`/${currentAppId}`)) {
    3. next(`/${currentAppId}/error`)
    4. } else {
    5. next()
    6. }
    7. })

7.2 静态资源404错误

原因:构建时未正确处理子目录路径
检查项

  1. 确认publicPath配置正确
  2. 检查资源引用是否包含完整路径
  3. 验证Nginx的alias配置

7.3 状态管理混乱

最佳实践

  1. 每个应用维护独立Vuex/Pinia实例
  2. 通过命名空间隔离状态
    1. // store/modules/appA.js
    2. export default {
    3. namespaced: true,
    4. state: () => ({ ... })
    5. }

八、性能优化建议

8.1 代码分割策略

  1. // vue.config.js
  2. module.exports = {
  3. configureWebpack: {
  4. optimization: {
  5. splitChunks: {
  6. chunks: 'all',
  7. cacheGroups: {
  8. appA_vendor: {
  9. test: /[\\/]node_modules[\\/]/,
  10. name: 'appA_vendor',
  11. chunks: 'initial'
  12. }
  13. }
  14. }
  15. }
  16. }
  17. }

8.2 预加载机制

  1. <!-- 在主HTML中预加载关键资源 -->
  2. <link rel="preload" href="/appA/static/js/chunk-vendors.js" as="script">

8.3 服务端缓存

  1. location /appA/static/ {
  2. expires 1y;
  3. add_header Cache-Control "public";
  4. }

九、未来演进方向

9.1 边缘计算集成

通过CDN边缘节点实现:

  • 动态路由决策
  • 请求本地化处理
  • 实时应用切换

9.2 WebAssembly支持

将计算密集型模块编译为WASM:

  1. const module = await WebAssembly.instantiateStreaming(
  2. fetch('/appA/wasm/module.wasm')
  3. )

9.3 Serverless架构

结合云函数实现:

  • 自动扩缩容
  • 按使用量计费
  • 无服务器部署

十、总结与建议

单域名部署多uni-app应用的核心价值在于:

  1. 成本优化:减少域名和服务器资源投入
  2. 管理简化:统一监控、备份和更新流程
  3. 体验提升:保持品牌一致性

实施建议:

  1. 从小规模试点开始(2-3个应用)
  2. 建立完善的CI/CD流程
  3. 实施渐进式迁移策略
  4. 定期进行性能基准测试

通过合理规划路由结构、严格隔离应用状态、优化资源加载策略,开发者可以在保持uni-app开发效率的同时,实现高效的多应用部署方案。

相关文章推荐

发表评论