Skip to content

uni-app Vue3+TypeScript+Vite 项目构建输出目录配置指南

问题背景

在 uni-app Vue3+TypeScript+Vite 项目中,开发者经常遇到一个困惑:为什么在 vite.config.ts 中配置 @dcloudio/vite-plugin-unioutputDir 参数后,构建结果的输出目录没有变化?

这个问题在 uni-app 官方 GitHub 仓库中也有相关讨论:Issue #3248

问题分析

1. Vite 配置无效的原因

vite.config.ts 中,无论如何配置以下参数,都不会影响最终的构建输出目录:

typescript
// ❌ 这些配置在 uni-app 中都无效
export default defineConfig({
  build: {
    outDir: "dist/custom", // 无效
  },
  plugins: [
    uni({
      outputDir: "dist/custom", // 无效
    }),
  ],
});

根本原因: uni-app 的构建系统有自己独立的输出目录控制机制,它会覆盖 Vite 的相关配置。

2. uni-app 构建系统的工作原理

uni-app 构建系统的输出目录优先级如下:

  1. UNI_OUTPUT_DIR 环境变量(最高优先级)
  2. 默认路径dist/build/h5(H5 平台)或 dist/dev/mp-weixin(小程序平台)

正确的解决方案

✅ 方法一:使用 UNI_OUTPUT_DIR 环境变量(推荐)

package.json 中配置构建脚本:

json
{
  "scripts": {
    "build:h5-test": "cross-env UNI_OUTPUT_DIR=dist/test/h5 uni build -p h5 --mode test",
    "build:h5-prod": "cross-env UNI_OUTPUT_DIR=dist/production/h5 uni build -p h5 --mode production",
    "build:mp-weixin": "cross-env UNI_OUTPUT_DIR=dist/mp-weixin uni build -p mp-weixin"
  }
}

重要提示:

  • 必须添加 -p 平台参数:明确指定构建平台(如 -p h5-p app-p mp-weixin),确保构建行为的一致性和可预测性
  • 推荐使用平台特定的输出目录:如 dist/test/h5dist/test/app-plus,便于管理多平台构建产物

前提条件: 需要安装 cross-env 依赖

bash
pnpm add -D cross-env
# 或
npm install -D cross-env

配置示例

以本项目为例,在 package.json 第 54 行:

json
"build:h5-test": "cross-env UNI_OUTPUT_DIR=dist/test/h5 uni build -p h5 --mode test"

重要说明:

  • -p h5 参数明确指定构建平台,确保构建行为的一致性
  • UNI_OUTPUT_DIR=dist/test/h5 将 H5 构建输出到专门的平台目录

执行构建后,H5 构建文件将输出到 dist/test/h5/ 目录,包含:

  • assets/ - 静态资源
  • static/ - 公共资源
  • uni_modules/ - uni-app 模块
  • index.html - 入口文件

实际测试验证

测试过程

我们进行了完整的测试来验证这个结论:

  1. 测试移除 vite.config.ts 中的 outputDir 配置

    • 结果:构建正常,输出目录仍为 dist/test
    • 结论:outputDir 配置无效
  2. 测试移除 vite.config.ts 中的 build.outDir 配置

    • 结果:构建正常,输出目录仍为 dist/test
    • 结论:build.outDir 配置无效
  3. 测试移除自定义 buildDir 变量

    • 结果:构建正常,输出目录仍为 dist/test
    • 结论:自定义变量无效

测试结论

只有 UNI_OUTPUT_DIR 环境变量能够有效控制 uni-app 的构建输出目录。

最佳实践建议

1. 简化配置

移除 vite.config.ts 中无效的配置:

typescript
// ❌ 可以移除这些无效配置
let buildDir = "dist/build/default";
if (command === "build") {
  if (mode === "production") {
    buildDir = "dist/build/h5";
  } else if (mode === "test") {
    buildDir = "dist/test";
  }
}

export default defineConfig({
  build: {
    outDir: buildDir, // 无效,可以移除
  },
  plugins: [
    uni({
      outputDir: buildDir, // 无效,可以移除
    }),
  ],
});

2. 统一使用环境变量

package.json 中为不同环境配置不同的输出目录:

json
{
  "scripts": {
    "build:app-test": "cross-env UNI_OUTPUT_DIR=dist/test/app-plus uni build -p app --mode test",
    "build:h5-test": "cross-env UNI_OUTPUT_DIR=dist/test/h5 uni build -p h5 --mode test",
    "build:app-production": "cross-env UNI_OUTPUT_DIR=dist/production/app-plus uni build -p app --mode production",
    "build:h5-production": "cross-env UNI_OUTPUT_DIR=dist/production/h5 uni build -p h5 --mode production"
  }
}

3. 推荐的目录结构

采用按模式和平台组织的目录结构:

dist/
├── test/                    # 测试环境构建产物
│   ├── h5/                  # H5 平台
│   ├── app-plus/            # App 平台
│   └── mp-weixin/           # 微信小程序平台
├── production/              # 生产环境构建产物
│   ├── h5/
│   ├── app-plus/
│   └── mp-weixin/
└── development/             # 开发环境构建产物
    ├── h5/
    ├── app-plus/
    └── mp-weixin/

这种结构的优势:

  • 清晰分离:不同环境和平台的构建产物互不干扰
  • 便于部署:可以针对特定环境和平台进行部署
  • 易于管理:构建产物组织有序,便于维护

总结

  1. uni-app 有独立的构建输出控制机制,不依赖 Vite 的配置
  2. UNI_OUTPUT_DIR 环境变量是唯一有效的输出目录控制方式
  3. vite.config.ts 中的 outputDirbuild.outDir 等配置在 uni-app 中无效
  4. 使用 cross-env UNI_OUTPUT_DIR=目标目录 是最简洁可靠的解决方案

这种设计虽然可能让从 Vite 转过来的开发者感到困惑,但它确保了 uni-app 跨平台构建的一致性和可控性。


本文档基于实际项目测试和 uni-app 官方 Issue #3248 的讨论整理而成。

Released under the MIT License.