尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

UniApp微信小程序多环境配置:从.env环境变量到域名白名单实战指南

发布时间:2026/9/29 16:43:52

资讯中心
01
ARTICLE

UniApp微信小程序多环境配置:从.env环境变量到域名白名单实战指南

UniApp微信小程序多环境配置:从.env环境变量到域名白名单实战指南
1. 多环境配置到底在解决什么问题做 UniApp 微信小程序开发的人迟早会撞上一堵墙开发时接口跑在本地或者内网 IP 上测试时要用测试服务器的地址正式上线又要切到备案过的 HTTPS 域名。你天天在代码里手动改baseURL改完还得记着上线前改成正式地址哪天忘了测试版被当成正式版发出去数据写错环境那场面基本就是事故现场。所谓多环境配置就是把开发、测试、生产这几套环境的参数从代码逻辑里剥出来统一放到配置层通过编译或启动流程自动选择。UniApp 本身又是跨端框架同一套代码要跑微信小程序、App、H5不同平台对不同环境的限制还不一样这就让这件事比普通 Vue 项目复杂了一层。这篇内容我按自己的实际工程经验来写适合正在做 UniApp 微信小程序、被域名白名单和接口地址切换折磨的开发者。你不需要用我的方案照搬但搞懂背后原理自己搭一套配置体系就不会再踩我踩过的坑。1.1 三个环境三种接口一套代码先场景化一下。开发环境里我的接口往往是http://192.168.1.100:8080/api这是本地后端服务可能连的还是开发数据库数据随便造随时能清。测试环境是公司内网或者云上的https://test-api.example.com/api部署了最新的测试包给 QA 用来回归。生产环境就是正式域名https://api.example.com/api所有数据都是真实的用户数据。这三个环境不只是接口地址不同往往还涉及其他东西小程序 AppID 可能不同测试环境用的是测试号或另一主体的小程序正式版用正式 AppID埋点上报地址不同开发环境上报了也白报日志级别不同开发环境恨不得打印所有日志生产环境必须关掉调试输出支付、登录、分享等功能依赖的商户号或密钥不同是否启用假数据、是否开启 Mock、是否走代理都有差异把这些硬编码在业务代码里是最糟糕的写法。比如有人在每个请求方法里写一个if (isProd) { url ... }当时看着挺聪明等环境增加到四个甚至五个代码会乱得没法维护。正确思路是业务代码永远只读一个配置对象配置对象由环境变量或构建流程决定。1.2 微信小程序的域名白名单卡住了多少人微信小程序有个和其它端不太一样的硬性规则线上小程序只能请求在公众平台后台配置过的合法域名而且必须是 HTTPS不能是 IP 地址加端口。开发工具里勾选“不校验合法域名”能临时绕过但真机预览、体验版、正式版都绕不过去。这意味着什么意味着你哪怕只是本地联调如果后端不是 HTTPS你真机根本调不通接口只能靠模拟器或开发工具。而到了测试阶段每个环境都要在对应的小程序后台里维护一份白名单生产环境加生产域名测试环境加测试域名。域名没加代码再对也白搭请求直接报domain is not in the following request whitelist。所以 UniApp 多环境配置从来不只是改个 baseURL 那么简单它实际上是一整套“环境变量 构建配置 微信后台域名维护 发布流程”的工程问题。先把这个认知建立起来后面每一步操作你才知道自己在干什么。1.3 不配环境的代价就是每次发布前改代码我见过不少团队项目启动时不搭多环境觉得“先跑起来再说”。到了即将上线那几天几个人围着一台电脑把代码里所有地址、AppID、密钥手动改成正式值改完测试一轮发现有遗漏再改一轮发布前人心惶惶。这种做法的代价不是一次两次改代码的功夫而是每次发版都在做高风险的人工操作。改错一个配置轻则接口全挂重则把测试数据导到生产库。UniApp 这种跨端项目还会带来额外问题H5 可能走的是同一个 baseURLApp 又有一套微信小程序再做一层域名校验。手动改一次就要在三端分别验一次工作量成倍上涨。所以我强烈建议就算你的项目再小也要在最开始把多环境这套东西搭好。一次性投入半天时间未来每一版发版节省的时间和避免的事故都远超这个成本。2. 选型为什么我用 .env 加统一配置入口多环境配置方案不少有人用config.js一堆 if-else有人用条件编译有人用.env文件还有人用发布平台的流水线变量。我的选型结论是以.env文件为主配合自己封装的统一配置读取入口同时用条件编译处理个别平台差异。这个组合不是拍脑袋定的而是针对 UniApp 项目的几个特点做的取舍。第一UniApp 现在新项目基本都是 Vite 构建Vite 天然支持把.env文件中的变量注入到import.meta.env中。第二.env文件是纯声明式配置谁接手都能看懂不需要读代码猜逻辑。第三配置和代码分开后同一套代码在不同环境构建只需要切换.env文件不会改乱业务代码。2.1 先搞清楚 process.env 和 import.meta.env 的区别这是新手最容易蒙的地方。UniApp 的 Vue CLI 老项目里环境变量通过process.env.XXX读取变量名必须带VUE_APP_前缀。而基于 Vite 的新项目里环境变量通过import.meta.env.XXX读取变量名必须带VITE_前缀并且只有VITE_前缀的变量才会被注入。比如你在.env.development里写了VITE_API_BASE_URLhttps://dev-api.example.com VITE_APP_ENVdev那么在代码里你只能通过import.meta.env.VITE_API_BASE_URL拿到它。如果你写了不加前缀的变量比如API_BASE_URLhttps://...它在 Vite 里默认是暴露给服务端构建用的不会注入客户端代码折腾半天拿到的永远是undefined。这个前缀机制是刻意的安全设计防止把敏感变量一股脑暴露到客户端代码里。我们的经验是所有需要在小程序端读取的变量统一用VITE_前缀命名用大写和下划线一目了然。2.2 HBuilderX 项目和 CLI 项目差异很大UniApp 有两种工程形态这也是很多人踩坑的根源。一种是直接用 HBuilderX 创建的项目不带完整 Node 工程结构.env支持非常受限。另一种是通过vue-cli或vite命令创建的 CLI 工程有完整的 Node 构建体系.env方案可以直接用。HBuilderX 项目里更靠谱的做法是条件编译。UniApp 在编译时会把代码里的条件注释按目标平台裁掉比如// #ifdef H5 const env h5 // #endif // #ifdef MP-WEIXIN const env weixin // #endif这能解决“平台差异”但解决不了“同平台不同环境差异”。所以 HBuilderX 项目通常还得配一个环境判断逻辑比如根据process.env.NODE_ENV区分开发版和正式版。HBuilderX 编译时会自动注入process.env.NODE_ENV开发运行是development发行打包是production这一点要活用。我自己更推荐 CLI 项目因为团队协作、持续集成、代码审查都更成熟。但如果你已经在 HBuilderX 项目里积攒了大量代码也不用推倒重来用“条件编译 统一 config.js”也能搭出多环境配置只是没有.env那么优雅。2.3 条件编译和 env 文件怎么配合一个好的工程里两者各司其职.env文件管“环境差异”条件编译管“平台差异”。举例来说微信小程序要求接口域名白名单里填 HTTPS 域名但 H5 开发时你可能要代理到本地避免跨域。这时候.env.development里可以设置VITE_API_BASE_URL/api然后 Vite 的 dev server 做代理而微信小程序端没有 dev server 的概念必须填完整地址。这类问题光靠.env解决不了你需要在封装的请求模块里加条件编译// #ifdef H5 const devBaseUrl /api // #endif // #ifndef H5 const devBaseUrl https://dev-api.example.com // #endif我见过不少团队只用一个方案要么所有环境差异写死在 config.js 里要么把所有平台逻辑塞进.env最后都出现了难以维护的迹象。把“环境”和“平台”这两个维度拆开配置系统的复杂度才会降下来。3. 从零开始配置一套多环境工程下面进入实操。我按一个标准 CLI 创建的 UniApp 项目为例带你完整配置开发、测试、生产三套环境。你不需要完全照抄我的目录但每一步的核心思路要跟上。3.1 目录设计和 .env 文件内容我一般会在项目根目录下维护四个文件.env公共变量所有环境共用的内容.env.development开发环境.env.staging测试环境.env.production生产环境有的人还会加.env.local这个文件一般不进 Git用来放本地私有覆盖项比如你本机连的某个特殊地址。.env里放公共内容比如应用名称、版本号前缀# .env VITE_APP_NAME我的小程序 VITE_APP_VERSION1.0.0开发环境的配置# .env.development NODE_ENVdevelopment VITE_APP_ENVdev VITE_API_BASE_URLhttps://dev-api.example.com VITE_LOG_LEVELdebug VITE_UPLOAD_URLhttps://dev-upload.example.com测试环境# .env.staging NODE_ENVproduction VITE_APP_ENVstaging VITE_API_BASE_URLhttps://test-api.example.com VITE_LOG_LEVELwarn VITE_UPLOAD_URLhttps://test-upload.example.com生产环境# .env.production NODE_ENVproduction VITE_APP_ENVprod VITE_API_BASE_URLhttps://api.example.com VITE_LOG_LEVELerror VITE_UPLOAD_URLhttps://upload.example.com注意我这里有意识地让NODE_ENV在 staging 环境也等于production。为什么要这样因为很多第三方库和 uni-app 自身的构建逻辑会检查NODE_ENV是不是production如果不是它会打进一堆开发调试代码导致测试包体积变大、性能变差。我们测试环境虽然面对的是 QA但本质上也在验证接近正式的行为所以NODE_ENV直接置成 production用自定义的VITE_APP_ENV来区分环境归属。3.2 在代码中读取环境变量的正确姿势不要在每个页面里到处直接读import.meta.env.VITE_API_BASE_URL那样一旦变量名要改全项目跟着遭殃。我习惯在src/config目录下建一个index.js把环境相关的东西收敛成一个配置对象// src/config/index.js const env import.meta.env const appConfig { env: env.VITE_APP_ENV || dev, appName: env.VITE_APP_NAME || 未命名应用, version: env.VITE_APP_VERSION || 0.0.0, apiBaseUrl: env.VITE_API_BASE_URL || , uploadUrl: env.VITE_UPLOAD_URL || , logLevel: env.VITE_LOG_LEVEL || debug } export default appConfig这个文件是整个客户端的环境信息唯一入口。页面上拿到的是appConfig.apiBaseUrl而不是直接跟import.meta.env打交道。好处有三个第一页面代码不会因为环境变量读取方式变化而改动第二配置项集中便于审查第三在开发环境调试时可以在这里打印一份当前环境完整配置。为了让团队里每个人知道自己跑的是哪个环境我还会在开发阶段把env显示在小程序页面的某个不起眼位置。比如设置页面里展示“当前环境dev / 1.0.0”这样测试人员提 bug 时直接报这个信息能省去大量沟通成本。3.3 请求封装一处切换全局生效多环境配置的核心价值最终要落到请求层。我用uni.request做一层封装在这个封装里填入appConfig.apiBaseUrl所有业务请求都走这个封装。下面是我常用的请求封装骨架// src/utils/request.js import appConfig from /config/index.js const request (options) { return new Promise((resolve, reject) { const url ${appConfig.apiBaseUrl}${options.url} uni.request({ url, method: options.method || GET, data: options.data || {}, header: { Content-Type: application/json, X-App-Env: appConfig.env, ...(options.header || {}) }, timeout: options.timeout || 15000, success: (res) { // 这里可以做统一的业务码处理 if (res.statusCode 200 res.data.code 0) { resolve(res.data.data) } else { uni.showToast({ title: res.data.msg || 请求失败, icon: none }) reject(res) } }, fail: (err) { reject(err) } }) }) } export default request核心逻辑就是把appConfig.apiBaseUrl拼到每个请求 url 前面。你切换环境时只需要换.env文件重新构建全项目的接口地址就都变了。这个封装里我还习惯加一个X-App-Env头后端可以根据这个头区分请求来自哪个环境方便排查线上问题。另外说一个实用小技巧appConfig.env除了用来展示还可以当做一个“功能开关”。比如开发环境自动展示一个调试悬浮窗测试环境允许查看接口返回值耗时生产环境全部关闭。用统一配置对象来控制业务功能比到处写if (process.env...)干净得多。3.4 微信小程序专属配置APPID、域名白名单与调试开关微信小程序除了代码里的环境变量还有几个配置必须按环境区分。第一是 AppID。开发时可以用测试号申请一个小程序测试 AppID这个 AppID 无法发布正式版但能把开发联调和正式发布完全隔离避免误操作。如果你有好几个环境我的建议是每个环境配一个小程序账号至少测试和生产要分开。生产环境填正式 AppID测试环境填另一个主体或测试号 AppID。在 UniApp 里小程序 AppID 配置在manifest.json的mp-weixin字段下{ mp-weixin: { appid: wx正式APPID, setting: { urlCheck: true }, usingComponents: true } }urlCheck是微信开发者工具里的 URL 校验开关。开发环境下有些人喜欢把它设成false这样工具里不会校验域名某种程度上方便但也会掩盖域名白名单问题。我的建议是开发时关闭调试方便测试和预发环境必须开启确保发版前暴露所有域名问题。第二是后台域名白名单。微信公众平台的后台里每个小程序账号要分别配置 request 合法域名、uploadFile 合法域名等。这里没有任何代码可以绕过只能是登录对应账号的后台把当前环境的域名加进去。生产环境尤其要注意线上域名变更时必须先加白名单再发代码否则一上线就是所有请求直接失败。第三是开发者工具的“不校验合法域名”开关。这个开关位置在“详情 - 本地设置 - 不校验合法域名”。它只对当前工具窗口有效真机预览依然会执行域名校验。所以正确习惯是本地调试归本地调试发体验版前一定要自查一遍所有请求域名是否已加入白名单。3.5 打包流程与版本核对配置搭好之后打包流程要固定下来。CLI 项目里执行命令看起来像这样# 开发环境运行微信小程序 npm run dev:mp-weixin # 测试环境打包 npm run build:mp-weixin -- --mode staging # 生产环境打包 npm run build:mp-weixin这里的关键是--mode stagingVite 用它来确定加载的是哪个.env文件。如果项目是用默认模板创建的package.json里的 scripts 一般长这样{ scripts: { dev:mp-weixin: uni -p mp-weixin, build:mp-weixin: uni build -p mp-weixin } }默认的build只会走 production 模式你需要在脚本里支持指定 mode。如果你的脚手架不支持可以自己加一行uni build -p mp-weixin --mode staging打包完成后要用微信开发者工具打开dist/dev/mp-weixin或dist/build/mp-weixin目录先看一眼请求地址是不是当前环境再继续后面的测试。我见过有人打包出来没留意apiBaseUrl还是上个环境的地址白测了半天。为了杜绝这个问题我在src/config/index.js里特意加了启动时打日志console.log([AppConfig] env${appConfig.env} api${appConfig.apiBaseUrl})打开开发者工具的控制台第一眼就能看到当前包用的哪个环境比事后猜要省心太多。4. 上线前必须检查的细节环境配置不是写完就完事上线前有几处细节最容易出问题我每次发版都要逐一过一遍。4.1 域名校验与 HTTPS 证书微信小程序对请求域名有三个硬性要求必须是 HTTPS必须已经备案必须在微信后台白名单中。其中证书环节特别容易被忽视。有些团队的测试环境用的是自签名证书或者过期证书开发工具里勾选“不校验合法域名”能过但是真机一访问就报证书错误而且是那种看起来非常不友好的request:fail。我踩过的一次坑是测试环境换了新域名证书也换了后台白名单也加了但真机仍然请求失败。排查了半天发现是证书链不完整只部署了域名证书中间证书链没配安卓微信客户端解析失败。这类问题在开发工具里往往因为工具自身忽略证书链而不明显但真机逃不掉。所以我的检查清单里有这么一条每个环境的 HTTPS 域名都要先用手机浏览器直接访问一下接口地址确认浏览器能正常拉取接口数据。浏览器都不行微信小程序必然不行。4.2 环境变量不生效的典型场景代码写得好好的但import.meta.env.VITE_API_BASE_URL打印出来是undefined这种问题我在各种技术群里见过太多次。究其原因无非以下几种变量没加VITE_前缀Vite 默认不暴露给客户端.env文件名不对Vite 只会按.env、.env.[mode]、.env.local等固定规则读取运行命令时的--mode传错了比如你想打测试包结果命令里传的是production加载了生产配置缓存问题Vite 构建缓存或者开发者工具缓存没清跑的还是老包排查方法很直接在src/config/index.js里把import.meta.env整个对象打印出来看一眼缺什么一目了然。如果显示完整但变量名不对基本就是前缀问题如果import.meta.env里压根没有你的变量那就是构建时就没注入去查命令和文件名。4.3 测试环境和生产环境的数据错乱问题这是多环境配置必须考虑的一个方法论问题环境隔离不仅是代码层的事还有数据层。我见过有人测试环境后端连的居然也是生产数据库导致测试人员每次操作都污染真实数据。环境配置文件里写地址只是第一步真正要保证的是从数据库、缓存、对象存储到第三方接口每个环境都应该是完整的独立一套。前端能做的至少是别把环境标识发错。我在请求封装里加的X-App-Env头就是干这个的后端可以依据这个头判断请求来源拒绝不是本环境允许的请求。比如测试环境的接口如果收到来自生产 AppID 的请求可以报警或者拦截。另外要提醒的是千万别在正式环境里把VITE_APP_ENV写成别的名字。这个值一旦错乱后端排查问题时看到的头全是错的定位问题的难度直接翻倍。我见过某个正式包发出去后后端看日志发现大部分请求的X-App-Env还是 staging马上一身冷汗最后查出来是构建时--mode参数写错了。4.4 灰度发布与小流量验证多环境配置搭好之后你还能得到一些额外收益灰度发布变得简单。微信小程序上线本来就是先提交代码到后台审核通过后发布发布时可以选择全量发布或分阶段发布。如果你的apiBaseUrl是空的客户端会拿着空地址去请求这显然不行。我的做法是生产环境的apiBaseUrl指向正式 API同时后端支持按用户维度切流到新版本服务。前端不需要为此做复杂的配置只要保证环境标识正确后端通过X-App-Env和用户标识决定路由到哪套服务。前端发布配合后端灰度一次发布就能在小流量下把问题都暴露出来比一次全量切换安全得多。5. 常见问题排错速查表实用内容放在最后。下面这些是我在真实项目中遇到过高频问题整理成表格便于你排查时快速定位。现象可能原因排查方法请求报url not in domain list域名未加白名单登录小程序后台检查 request 合法域名请求报request:fail域名证书问题、Https 失效、IP 加端口用手机浏览器访问接口地址验证import.meta.env.XXX为 undefined变量未加VITE_前缀打印完整import.meta.env对象打包后还是旧环境地址--mode参数错误或构建缓存清空 dist 目录重新打包检查启动日志真机请求失败但开发工具正常开发工具勾了不校验域名真机预览时关闭该选项自测测试包体积异常大NODE_ENV不是 production检查.env.staging的 NODE_ENV后端日志看到异常环境头.env文件被误改或构建命令不对使用 CI 固定构建命令禁止手动打包上线后部分用户接口不通域名变更未全量验证手机浏览器访问、小程序体验版先验证5.1 我常用的一个检查动作这里多说一个我自己的习惯可能对你有帮助。每次打完包我不急着打开开发者工具而是先跑到dist/build/mp-weixin目录下把app-config相关的编译产物翻出来看一眼或者直接看项目启动日志里打印的[AppConfig] env... api...。确认环境没错再打开微信开发者工具。这一步只要十秒钟但能避免一整个下午的无效测试。因为你一旦带着错误的包开始测试后面所有结论都可能被误导。5.2 团队协作时的配置规范最后说点规范层面的经验。多环境配置牵扯到的不只是个人开发还有团队协作。我建议几条约定.env.local一律不进 Git每个人的本地覆盖只留在自己机器.env.*文件都要写注释说明每个变量的用途构建命令统一维护在package.json的 scripts 里禁止成员自定义参数每个src/config/index.js变更必须 code review避免有人把环境变量硬编码到业务代码里我在实际使用中最大的感受是多环境配置其实没有多少高深技术难的就是把约定坚持下来。只要团队里有人在某个页面里直接写了一个http://192...的接口地址配置体系就开始被破坏。遇到这种情况我的处理方式是先用代码注释标出来然后快速改成从appConfig读取不让任何一行不属于当前配置的值流落到业务代码里。这套东西说起来朴素但它让我从“每次发版前祈祷别忘改地址”变成了“打到一个包就知道它是什么环境”。如果你也在做 UniApp 微信小程序我建议现在就花半天时间把工程里的环境配置整理一遍。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。