4.3 工程化心得:多环境、CI 部署与模拟器测试

用法会决定工程质感。Firebase 上手极快,快到很容易一鼓作气把原型直接跑成生产,等想补工程化时,地基已经歪了。这一节聊三件我建议一开始就做对的事:环境隔离、CI 部署、模拟器测试。

多环境:三个项目,一个都不少

社区里常见的争论是:多环境到底该用一个 Firebase 项目切来切去,还是建多个项目。我的答案是后者,而且是三个:dev、staging、prod 各一个独立项目。

理由很直接:项目级别的隔离是硬隔离。数据、规则、认证配置、扩展,全部天然分开,dev 上怎么折腾都碰不到 prod。反之,一套项目乱切,靠的只是集合前缀或环境字段这类软约定,一次手滑的部署、一条忘改的规则,就足以让测试数据进生产库,或者更糟——让生产规则被测试配置覆盖,把锁得很好的库瞬间开成裸奔。

我的项目划分习惯:

  • dev:日常开发,规则可以适当放宽,数据随便造、随便清
  • staging:接近生产的彩排场,规则与 prod 保持一致,用假数据做集成验证
  • prod:只接受通过验证的部署,日常开发不碰
环境 用途 注意
dev 日常开发与试错 规则可放宽,但也不建议全放开,保持好习惯
staging 上线前集成验证与规则彩排 规则与配置尽量和 prod 同步
prod 面向真实用户的生产环境 只接受 CI 触发的部署,禁止本地直连生产部署

配置分离与切换脚本

三个项目意味着三份前端配置。做法很简单:按环境各留一份配置文件,构建时注入对应环境的配置,再用切换脚本或 CI 变量控制注入哪一份。原则只有一条:环境信息属于构建期决定的事,不要让运行时去猜,更不要让人在代码里手动改来改去。

部署脚本同理。部署到哪个项目,用 firebase use 显式指定,并把它写进 CI 流水线步骤里,而不是依赖某台本地机器上一次 use 过什么。

CI 部署:凭据与改动面

把部署从某个人某台电脑上挪到 CI,是工程化的分水岭。要处理好两件事。

一是凭据。不要把个人账号的长期登录凭据共享给 CI,正确姿势是为 CI 建专门的服务账号,凭据放进 CI 平台的密钥管理,并只授予部署所需的最小权限——谁需要部署什么项目、什么产品,就给什么权限,不要全项目管理员一把梭。

二是改动面。firebase deploy 不带参数会部署一切,规则、函数、托管全上,在 CI 里既慢又危险。用 --only 明确这次要动什么:只发函数、只发托管、只更新规则。改动面越清晰,回滚和排查越容易。

模拟器套件:把测试成本打到接近零

Firebase 提供本地模拟器套件,能在本机把 Firestore、Functions、认证等核心产品跑起来,规则测试尤其有价值。细节与覆盖范围以官方文档为准,这里只说它改变了什么:

  • 不烧钱:所有读写发生在本地,测试用例怎么跑都不产生云端费用
  • 不污染:测试数据和规则试验完全不碰真实项目
  • 可回归:规则可以写成单测,每次改动在 CI 里跑一遍,规则变更从此有回归保障

写规则单测的思路很朴素:把每条规则的正反两面都写成用例。允许的场景要真的能通过,拒绝的场景要真的被拦下,别靠人肉在生产控制台里点来点去验证。

接入模拟器的简要清单:

  • [ ] 安装模拟器工具并初始化所需产品
  • [ ] 前端与脚本通过模拟器连接配置指向本地
  • [ ] 准备测试数据种子,用例之间互不依赖
  • [ ] 规则单测覆盖允许与拒绝两条路径
  • [ ] 把模拟器测试接入 CI,作为部署前置步骤

一张表收尾:

环节 建议 常见反模式
环境划分 三个项目硬隔离 一套项目靠软约定乱切
配置管理 构建期注入,脚本切换 运行时猜环境,手动改代码
CI 凭据 专用服务账号,最小权限 共享个人长期凭据
部署范围 用 --only 明确改动面 无参数全量部署
测试 模拟器加规则单测进 CI 人肉在生产环境验证规则

工程化这些事,晚做不如早做,早做不如一开始就做对。它们增加的工作量有限,却决定了项目从原型到产品的路能走多稳。