如果你是从 GitHub 上拉过一个带cloudfunctions目录的微信小游戏项目,大概率见过这个画面:云开发面板打开,云函数列表空荡荡,顶部赫然写着“未选择环境”。右键上传部署的菜单全是灰的,控制台报错也报得不痛不痒。我第一次碰到时以为开发者工具坏了,重装了一遍问题照旧。后来才琢磨明白,这里根本不是工具的事,而是项目跟云端环境的关联压根没建立起来。
不管你是用 Unity 打包转出来的微信小游戏,还是手写原生 JS 代码,只要工程里挂着一个cloudfunctions目录,早晚都要面对“环境选择”这道坎。这篇文章我就按自己实际踩坑的排查顺序,把“未选择环境”的成因和完整解决办法说清楚,适合所有遇到云开发环境选择问题的小游戏开发者,尤其是刚拿到开源项目、对着面板发呆的新手。
1. 显示“未选择环境”不是工具坏了,是环境关联没建立
1.1 问题现场:云函数列表空白,上传菜单全灰
先说说具体现象,省得你对不上号。打开微信开发者工具,导入小游戏项目,点工具栏里的“云开发”按钮,面板能正常弹出来,但里面云函数列表是空的。面板顶部环境那一栏,明晃晃写着“未选择环境”。
这时你右键cloudfunctions目录下的任意函数文件夹,会发现“上传并部署”是灰色的,选都选不了。有人可能想用命令行工具强推,结果 CloudBase CLI 那边也报找不到环境。整个状态就是:东西都在本地,但工具不知道把代码传到哪里。
我当时在多个社群里看到大家的第一反应都是“工具坏了”或者“需要重装”,实际上这两条路都走不通。我重装工具、清缓存、重新登录,折腾了大半天,最后发现是项目配置的问题。
1.2 环境关联的三方暗号机制
要真正理解这个报错,得先弄清楚微信开发者工具是怎么认定“云函数归属”的。我的理解是,它需要三方对上暗号:
- 云端确实存在一个云开发环境,带唯一的
envId(环境ID),比如cloud1-3g4h5j - 项目配置文件里声明了云函数目录的位置,也就是
cloudfunctionRoot - 代码里调用
wx.cloud.init,并且指定了要连接哪个环境
这三件事,少一件,面板就会摆出一张“未选择环境”的脸。最典型的场景是:你微信账号下只有一个环境 A,但项目代码和配置里写的全是原作者的另一个环境 B。工具编译完代码,发现环境 B 在当前账号下根本不存在,自然就选不出来,于是干脆给你显示“未选择环境”。
这里要特别提醒一句:网上很多教程只让你在工具面板里点两下,却没说为什么点了还是不行。原因就在于,面板手动选择环境只是其中一环。如果代码里wx.cloud.init写死了别人的环境ID,你在面板选了也没用,运行时照样连不上那个不存在的环境。所以别急着认为面板选一下就是全部答案。
2. 动手之前,先确认你手里有没有环境
2.1 控制台查环境和环境ID
解决问题的第一步不是改代码,而是先确认自己账号下到底有没有可用的云开发环境。打开微信云开发控制台,用和开发者工具同一个微信号登录。控制台首页会列出你名下的所有环境。
如果列表是空的,就点“新建环境”。创建时注意环境ID和环境名称是两个概念:环境名称是给人看的,比如“测试环境”“生产环境”;环境ID才是代码和配置文件里真正要写的那一串,格式通常是短横线连接的随机串,比如cloud1-7g8k2x。在控制台的环境设置里就能看到环境ID,直接复制保存好。
这里有个小经验:新手经常把环境名称当环境ID填进wx.cloud.init,结果怎么调都不通。记住了,只要是写给代码和配置文件的,一律用环境ID。
2.2 开源项目最常见的坑:环境是作者的
接下来这点很关键。我遇到的“未选择环境”,十有八九是因为项目是别人的。
从 GitHub 或其他渠道拉下来的开源项目,作者在自己电脑上写好了环境ID,这个 ID 在他的账号下有效,但在你的账号下查无此环境。例如作者的代码里是:
// game.js wx.cloud.init({ env: 'cloud1-author-env-id', traceUser: true })这个env指向的环境,在你的微信账号里根本不存在。工具自然没法选中,于是显示“未选择环境”。你要做的,就是把这个环境ID替换成你自己的,然后再到工具面板里选自己的环境。
这里要特别提醒 Unity 或者 Laya 转小游戏过来的开发者:微信小游戏的入口文件是game.js,不是app.js。用 Unity 导出的工程,入口文件往往藏在编译产物里,找入口时不要死盯着app.js不放,去看game.json里配置的启动入口是哪个文件,云开发的初始化逻辑写在那里。
2.3 测试号与正式AppID对云开发的影响
还有一个经常被忽略的前置条件:AppID 的类型。如果你用的是开发者工具默认的“测试号”,那终究走不到云开发这一步。测试号没有云开发权限,也不会有真实环境,面板自然永远显示“未选择环境”。
遇到这种情况,先去微信公众平台注册一个小游戏账号,拿到正式的小游戏 AppID。个人主体也可以用,云开发的基础版有免费额度,适合个人项目起步。把正式 AppID 填进project.config.json,开发者工具里重新登录,云开发面板才会同步到你的真实环境列表。
3. 解决“未选择环境”的三层配置,从界面到代码
3.1 第一层:云开发面板手动选环境
确认环境存在之后,回到微信开发者工具。点工具栏的“云开发”按钮,打开云开发面板。面板顶部会有环境选择的下拉框,点开,选择你刚才确认好的那个环境。如果你的账号只有一个环境,工具通常会自动帮你选上;有多个环境的,手动确认一下当前选的是哪个。
做完这一步,云函数列表一般就出来了,“未选择环境”的提示也就暂时消失了。但先别急着庆祝。面板选对了,不代表上传云函数就完全畅通了,下面两层配置只要有一层对不上,上传时照样会出幺蛾子。
3.2 第二层:project.config.json 声明云函数目录
第二层是项目配置文件。如果你的项目里压根没声明cloudfunctions目录,开发者工具不知道去哪找云函数,云函数列表就是空的,上传更是无从谈起。
在微信小游戏项目根目录下,找到project.config.json,确保有下面这样的配置:
{ "compileType": "game", "cloudfunctionRoot": "cloudfunctions/", "appid": "wx你的真实AppID", "projectname": "你的项目名", "setting": { "es6": true, "urlCheck": false } }cloudfunctionRoot这个字段就是告诉工具:云函数目录在哪。路径从项目根目录算起,一般默认是cloudfunctions/。如果你的目录叫别的名字,比如cloud-functions/、functions/,这里的值就得对应改成实际目录名。
注意一点:新版开发者工具的某些模板里也会出现cloudbaseRoot这个字段,作用和cloudfunctionRoot类似。两个字段同时出现时,工具到底读哪个,不同版本行为有差异。我的建议是保留cloudfunctionRoot,兼容性最好;如果发现配置了cloudfunctionRoot但工具不识别,检查一下是不是工具版本太老,升级后一般都能解决。
3.3 第三层:game.js 里 wx.cloud.init 指定 env
第三层,也是最容易踩坑的一层:代码初始化。无论面板怎么选,小游戏运行时只有wx.cloud.init发了话才算数。在入口文件game.js的顶部,加上这一段:
wx.cloud.init({ env: '你的环境ID', traceUser: true })env必须是环境ID,不是环境名称。把云开发控制台里复制到的环境ID原样填进去,一行代码就能解决大部分“未选择环境”的运行时问题。
如果你原来写的是不带env的版本:
wx.cloud.init({ traceUser: true })在单环境的账号下,这样一般也能跑,工具会自动选默认环境。但账号下只要有多个环境,不带env就可能选到不想用的那个,甚至干脆选不出来。表现刚好就是云函数列表空转、提示未选择环境。所以不管什么情况,我都建议显式把env写上,一劳永逸。
顺带说一句,云开发环境ID不算敏感信息,在开发者工具里本来就是完全可见的,不用像对待 API Key 一样把它藏着掖着。真正的权限安全,靠的是后续云函数的权限配置和数据库安全规则。
4. 多环境切换与 DYNAMIC_CURRENT_ENV 的取舍
4.1 为什么会默认选到错误的环境
有开发者问过我:为什么我账号下明明有环境,工具还是显示“未选择环境”或者执意选中我不想要的那个?
原因是这样的:当你账号下有多个云开发环境,工具需要决定哪个是当前项目的默认关联环境。如果代码里wx.cloud.init没指定env,工具会尝试按内部规则猜,比如按环境创建时间选第一个,或者沿袭项目配置文件里残留的历史选择记录。如果这些信息对不上当前账号的实际情况,就会出现“选不出来”或者“选错人”的尴尬局面。
我之前维护一个项目时,开发环境叫dev,生产环境叫prod,面板里默认选中了dev,但小程序线上版本连的是prod。结果我在工具里写了个测试云函数,右键“上传并部署”时选成了dev,线上环境那边一点变化没有,我却在本地调试老半天,以为代码有 bug。
这类问题的根源,就是“面板选中环境”和“代码指定环境”没有保持一致。面板只管这单次操作传到哪,代码才管线上运行时连到哪。两条线不在一个环境上,早晚要翻车。
4.2 云函数内部建议用动态当前环境
再往前一步,云函数运行时的环境匹配,也有学问。当你把同一个云函数分别部署到dev和prod两个环境,云函数里如果要初始化服务端 SDK,最好采用动态匹配的方式:
// 云函数内 index.js const cloud = require('wx-server-sdk') cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV })DYNAMIC_CURRENT_ENV的意思是“当前环境”,即这个云函数被部署到哪个环境,运行时就自动连接哪个环境。这样写的好处是,同一个云函数代码,不需要在不同环境间改来改去,上传到 dev 就跑 dev,上传到 prod 就跑 prod,行为完全和环境隔离。
但要强调一下,这解决的是“云函数内部连哪个数据库、调哪个接口”的问题,不是工具栏“未选择环境”的解决方案。前面文章里讲的都是工具层面的关联,别把这两个问题混为一谈。碰到“未选择环境”,按第 3 节的流程走;碰到“云函数跑起来但数据不对”,再检查是不是没用动态当前环境。
4.3 开发/生产环境隔离的配置习惯
多环境场景下,为了少出幺蛾子,我自己养成了一些配置习惯,分享给大家参考:
- 本地开发时,
game.js里的wx.cloud.init固定写dev环境的环境ID - 发布体验版或线上版前,把
game.js的env切换成prod环境的环境ID - 云函数内部统一用
cloud.DYNAMIC_CURRENT_ENV,不做任何硬编码 project.config.json里只保留cloudfunctionRoot,不掺入环境ID相关的字段
这样配置下来,工具面板选什么环境,只影响你当前手动操作的云函数上传;线上到底跑哪个环境,完全由game.js和云函数内的DYNAMIC_CURRENT_ENV决定。职责清晰,排查起来也很省心。
有个进一步的小技巧:如果你经常切换环境,把两个环境ID写成一个配置文件,在云函数里做一次读取:
const envMap = { dev: 'cloud1-dev-env-id', prod: 'cloud1-prod-env-id' } wx.cloud.init({ env: envMap.develop || envMap.production, traceUser: true })再配合构建时的环境变量替换,能减少许多手动改代码的失误。不过这套方案对小项目来说有点重,只有团队协作或多环境并行时值得投入。
5. 完整排查链路与隐藏坑记录
5.1 按顺序排查的完整流程
如果你现在正好卡在“未选择环境”,别东一榔头西一棒子,按下面这个顺序一步步来,基本能定位问题:
第一步:确认 AppID 不是测试号。看开发者工具右上角,如果是“测试号”,先换正式 AppID。这一步错了,后面全白搭。
第二步:确认云端有环境。登录云开发控制台,看看账号下有没有环境列表。没有就新建一个,记下环境ID。
第三步:检查project.config.json。确认有compileType: "game"和cloudfunctionRoot: "cloudfunctions/"。路径写错或者漏掉字段,工具就找不到云函数目录。
第四步:检查game.js的初始化代码。确认wx.cloud.init里env是你自己的环境ID,检查入口文件路径对不对,Unity 转出来的项目尤其要核实。
第五步:在开发者工具面板重选环境。打开云开发面板,切换一下环境下拉框,让工具重新读一次环境列表。这一步也能处理部分面板缓存异常的情况。
第六步:验证上传。右键cloudfunctions下的具体函数目录,选择“上传并部署(云端安装依赖)”。如果能看到上传进度,说明环境关联已经打通。
5.2 我踩过的几个隐藏坑
最后聊几个容易被忽略的坑,每个都是我拿时间换来的教训。
坑一:只改了game.js的 env,没改project.config.json。有一次我把game.js里的环境ID换成了新环境,面板还是显示“未选择环境”。排查半天,发现是project.config.json里的cloudfunctionRoot路径写错了,工具根本没识别到云函数目录。代码层面改得再好,工具找不到目录也白搭。
坑二:删掉云函数目录里的 node_modules 倒不会导致“未选择环境”,但会导致“上传后无法运行”。很多人磁盘空间紧张,喜欢把云函数本地安装的依赖删掉,觉得“反正云端安装依赖”。但如果你右键选择的是“上传并部署(不上传依赖)”,云端就没有wx-server-sdk,函数一调用就报模块不存在。这个坑和本文主题不是同一个,但很容易连着踩。
坑三:开发者工具版本太老,读不到新配置。我有一段时间用旧版本工具,配置了cloudfunctionRoot但面板死活不认。升级到最新版后,问题自动消失。遇到环境相关的问题时,先看一眼工具版本号,新版对云开发的支持完善很多。
坑四:把环境名称当环境ID。这个前面提到过,但值得再说一遍。环境名称是我的开发环境这种人类友好的名字,环境ID是cloud1-xyz123这种。填错时不会立刻报“未选择环境”,但运行时会提示环境不存在,或者干脆拿不到数据。
坑五:环境关联成功后,换电脑又要重来一次。云开发的环境关系是跟着账号和项目配置走的,换台电脑登录同一个微信号,重新导入项目,game.js里已经写好的 env 会生效,但面板还是要手动选一次环境。这不是 bug,是工具的正常机制,提前知道就不慌。
按这套链路排查下来,绝大多数“未选择环境”都能解决。微信小游戏云开发这块,环境设置属于最基础也最磨人的环节,把环境ID、云函数目录、初始化代码这三者理清楚,后面做数据存储、调用云函数就顺滑多了。前几天我帮一个用 Unity 做小游戏的朋友处理同样的问题,他看了一遍上面的排查步骤,十分钟就搞定,跟我说早知道这么简单,就不该把工具卸载重装了。