uni-app 的 app 端 api 地址和 manifest 字段无法通过 process.env 直接控制,必须通过 prebuild.js 预生成 manifest.json、cross-env 注入环境变量、webpack environmentplugin 替换代码中变量三者协同实现。

uni-app 不能靠 process.env 直接控制 App 端的 API 地址或 manifest 字段,必须通过构建前预处理 + manifest.json 动态生成 + 环境变量注入三者配合才能生效。
manifest.json 的环境字段不被 process.env 覆盖
App 打包时,manifest.json 会被编译为原生配置(AndroidManifest.xml / Info.plist),此时 process.env 已经不可用。你在 JS 里写的 process.env.UNI_API_URL 在 App 运行时是 undefined,哪怕你在 .env.production 里写了也白写。
- manifest.json 中只有少数字段支持变量替换,比如
name、description、appid(小程序)、package(Android)等,且必须用UNI_*前缀的环境变量 -
networkTimeout、usingComponents等字段不接受变量,硬写进去也不会被替换 - iOS 的
CFBundleDisplayName和 Android 的applicationLabel都依赖 manifest.json 的name字段,所以改标题必须走 manifest 注入
用 cross-env + preBuild.js 动态生成 manifest.json
这是目前最稳定、CI 友好、多地区多平台兼容的做法:在 webpack 启动前,根据 NODE_ENV、UNI_PLATFORM、DISTRICT、DEPLOY 等变量,生成对应 manifest.json 文件。
- 在
package.json脚本中用cross-env注入:"build:app:anhui:prod": "cross-env NODE_ENV=production UNI_PLATFORM=app DISTRICT=anhui DEPLOY=prod vue-cli-service uni-build" - 新建
scripts/preBuild.js,读取process.env.DISTRICT和process.env.DEPLOY,合并对应地区的配置模板(如config/anhui.manifest.json) - 把最终结果写入项目根目录的
manifest.json,再执行uni-build;注意该文件需加进.gitignore,避免污染 - 不要在
vue.config.js里用fs.writeFileSync写 manifest —— 它运行时机晚于 manifest 解析阶段,无效
环境变量必须用 EnvironmentPlugin 注入到代码中
只改 manifest.json 不够,业务代码里还得拿到当前环境的 API 地址。不能依赖 process.env 原始值,要让 webpack 把它替换成字符串常量。
- 在
vue.config.js中使用configureWebpack.plugins加入:new webpack.EnvironmentPlugin(['API_BASE_URL', 'APP_TITLE']) - 确保这些变量已在
preBuild.js中设置进process.env,例如:process.env.API_BASE_URL = config.api[process.env.DEPLOY] - 这样你在组件里写
console.log(process.env.API_BASE_URL),打包后实际是console.log("https://api.anhui.example.com"),不是 undefined - 别用
DefinePlugin手动定义 —— 它无法识别process.env.XXX的嵌套结构,容易漏掉
小程序平台要额外处理 appid 和 conditional compile
微信/支付宝小程序的 appid 是 manifest.json 的顶层字段,但不同甲方项目不能共用一个,必须按环境动态填入。同时,部分页面或 API 调用需要条件编译,不能靠 JS 判断。
- 在
preBuild.js中,根据process.env.UNI_PLATFORM和process.env.DISTRICT查表填入appid字段,例如:manifest.mp-weixin.appid = appids[dist][platform] - 条件编译仍要用
#ifdef MP-WEIXIN这类语法,它在编译期剥离,和环境变量无关;但appid这种运行时才需要的值,必须靠 manifest 注入 - 如果用了自定义插件(如地图、推送),它们的 key 或 secret 也得走同一套
preBuild.js → manifest.json → EnvironmentPlugin流程,否则上线后调不通
真正容易被忽略的是:manifest.json 的修改必须发生在 uni-build 命令执行前的瞬间,且不能被 HBuilderX 的缓存覆盖;一旦你用 HX 点击“发行”,它会跳过 CLI 构建流程,直接读取旧 manifest —— 所以多环境打包必须弃用 HX 发行,全程走命令行。











