Nonmotor 前端开发指南:从需求到交付#
这份指南面向准备接手 Nonmotor 前端需求的后端工程师。以一个投保信息页需求为主线,说明项目为什么这样组织、如何跑起页面、怎样选择配置或代码实现,以及如何联调和交付。
读完并完成练习后,应能独立做到:从业务 URL 找到代码,判断需求改动范围,追踪字段到后端请求,并提交有验证证据的 MR。
阅读路线与分享安排#
| 阶段 | 章节 | 要回答的问题 | 阶段产出 |
|---|---|---|---|
| 认识项目 | 1. 项目与业务边界 | Motor 与 Nonmotor 有何区别?为什么采用不同的页面组织方式? | 能说明目标产品的页面链路和复用边界 |
| 跑通环境 | 2. 本地环境与启动;3. 调试方式 | 怎样用本地代码打开真实业务页面?怎样检查 App 内行为? | 可访问的本地页面、正确的接口环境与调试工具 |
| 定位实现 | 4. 从 URL 到代码;5. 需求分析与方案 | 入口在哪里?改配置、改组件,还是改接口? | 影响清单、实现方案与验收场景 |
| 完成开发 | 6. Journey 与数据流;7. 开发约定;8. 贯穿案例 | 页面怎样生成?一个字段怎样到达后端? | 配置/代码改动、完整字段数据流 |
| 验证与交付 | 9. 联调自测;10. MR 与发布;12. 完成标准 | 如何证明行为正确?交付包含哪些物料? | 自测记录、MR、发布与回退说明 |
| 持续上手 | 11. 工具与 AI;13. 后续专题 | 如何提高效率、进一步掌握差异化与上线控制? | 下一步练习和专题学习计划 |
第一次阅读按第 1—10 章走完整流程;实际开发时用第 12 章检查完成度。分享现场的讲解顺序、演示和时间安排见分享提纲。安装细节和附录用于课后查阅,无需在现场逐条朗读。
本文依据 2026-10-09 至 2026-10-10 核对的工作区源码、团队提供的截图和已确认操作约定整理。业务项目的新环境安装、真实产品端到端流程及部署尚未在本次文档整理中实测;登录、权限和负责人等待补信息统一列在附录 A。源码依据见附录 B,市场代理规则见附录 C,Motor 各市场流程详解见附录 D。
1. 项目介绍:先认识业务与复用边界#
本章先建立项目认知:用户经过哪些页面、Motor 与 Nonmotor 为什么分开组织、哪些能力可以复用。入口注册和模板内部实现分别在第 4、6 章展开。
1.1 Motor 与 Nonmotor 的区别#
Motor 主要承载车险,Nonmotor 承载非车险。两者都会经过产品选择、信息填写、报价/确认和支付,但 Checkout 之前的页面组织方式不同:Motor 以市场专属页面为主,Nonmotor 的产品工厂主流程以共享模板和 Journey 配置为主。
对后端同学来说,可以先这样理解:Motor 由各市场的页面代码编排本地业务;Nonmotor 把高度一致的页面骨架、表单和交互做成可复用能力,再由产品工厂描述某个产品应该使用哪些能力。
| 对比项 | Motor:车险 | Nonmotor:非车险产品工厂流程 |
|---|---|---|
| 业务关注点 | 车辆、车主/驾驶人、历史保单、报价、附加保障,以及市场专属材料和步骤 | 产品保障、Plan、保障期间、投保人/被保人信息,以及产品所需的扩展字段 |
| Checkout 前的页面组织 | 按市场维护页面,例如 src/pages/my/、sg/、id/motor/ |
多个市场复用 src/pages/factory/、factoryV2/ 下的模板与组件 |
| 页面结构与流程 | React 页面、市场组件及业务条件共同编排 | 模板执行 Journey 中的页面、区块、字段、步骤和路由配置 |
| 差异主要放在哪里 | 市场页面、model/service、组件、状态与导航处理 | Journey、产品数据、翻译,以及必要的产品/市场扩展代码 |
| 复用特点 | 完整业务页面和专属组件跨市场复用较少;UI、表单、请求等基础能力仍能共用 | 产品间、市场间的页面和功能组件高度一致,适合共享模板与配置复用 |
| 拿到需求先查什么 | 哪个市场、哪条 Motor 流程、哪个页面或业务组件 | 哪个产品、哪份 Journey、哪个模板/区块/字段,已有能力能否表达 |

图 1:两种组织方式的核心差异在 Checkout 之前。图中是源码结构示意,不是真实产品 UI 截图;可点击放大。
业务分类、应用配置、源码目录和维护仓库需要分别确认,具体定位方法见第 4 章。
1.2 为什么采用不同的页面组织方式#
按照团队当前的业务划分,Motor 页面相对复杂,很多业务组件与市场流程强相关,跨市场难以直接复用;Nonmotor 不同市场、产品的页面结构和功能组件高度一致,复用收益更高。源码中的“市场目录”与“共享 Factory 模板”体现了这一设计取向。
| 设计判断 | 代码中的具体表现 | 对开发的意义 |
|---|---|---|
| Motor 的流程差异较大 | ID 有车辆配件/附加保障编辑分支;MY 有报价卡片和车辆信息编辑;SG 按保障决定是否经过 Add-ons | 先理解目标市场的页面状态、缓存和导航条件,再修改业务逻辑 |
| Nonmotor 的主结构一致 | 多市场的 PDP6、Purchase5 等入口指向同一份 Factory 源码 | 同一种字段、区块、校验能力可以服务多个产品,避免逐产品复制页面 |
| Nonmotor 的差异通常可以参数化 | Journey 的 blocks、entries、props、dependencies、constraints、stepItems 等参与页面生成 | 已有能力范围内,优先调整配置、翻译和数据;新行为再扩展代码能力 |
| 共用代码会扩大影响面 | 修改共享 FillInfo 或解析器,会影响使用它的其他产品/市场 | 回归范围应按“谁消费这项能力”确定,不能只验证当前产品 |
这不是绝对隔离。Motor 也会复用 MoneeDesign、InsEntry、Bridge、请求、缓存和部分业务组件;Nonmotor 也保留市场适配,例如 purchase5/config/{region}、PDP 的市场插入规则,以及 PHApplicant 等专属区块。应复用稳定共性,同时保留明确的市场/产品扩展点。
1.3 用户实际经过哪些页面#
两类业务的共同目标都是让用户了解保障、提供投保信息、确认方案并支付。差别在于 Checkout 之前如何拆页、组织交互和复用实现。

图示根据源码导航与配置整理,表示典型路径;产品、续保和可选分支可能改变实际顺序。
| 业务 | 典型链路与主要差异 |
|---|---|
| ID Motor | 车辆信息/PDP → 报价 → 个人信息确认 → Checkout;报价页可打开配件与附加保障编辑 |
| MY Motor | PDP → 报价列表 → 报价详情 → Checkout;摩托车和历史版本有不同分支 |
| SG Motor | PDP → 报价列表 → 报价详情 → 可选 Add-ons → 投保表单 → Checkout |
| Nonmotor 产品工厂 | PDP → Purchase → Confirmation → Checkout;由具体产品配置决定步骤,部分页面可以合并或跳过 |
Motor 按市场查页面,完整目录截图、页面文件名和源码依据见附录 D。Nonmotor 在多个市场复用 Factory 模板,当前 MY、ID、SG、TH 注册了同一组 PDP6、Purchase5、Confirmation 入口,但其他市场的页面集合并不完全相同。
Checkout 的边界#
Nonmotor 的“模板引擎 + 产品工厂”主要描述 Checkout 之前的产品工厂页面。收银台采用独立的 checkoutV2 实现,处理金额、优惠、支付选项及创单衔接,并保留市场适配。Motor 与 Nonmotor 可以共用收银台源码,传入的数据、应用与市场构建仍然不同。
前端负责交互、展示和及时校验;金额、资格、报价和创单结果应以对应后端契约为准。一个浏览器页面能打开,不等于 App 内完整下单流程已经通过。
1.4 页面最终由什么决定#
实际页面来自几个部分的组合:前端代码、产品 Journey、接口数据、翻译、PFC 配置以及运行环境。
因此,“页面不对”不一定意味着要修改 React 代码。某个字段没有出现,可能是 Journey 没有配置、显隐条件未命中、组件名未匹配,也可能是当前产品或市场选错。
还要区分两个常见概念:
- Journey:产品工厂下发的页面、区块、字段及相关规则,常通过
query_product_factory_journey获取。 - PFC:项目使用的配置能力,按配置下发条件提供数据。它可以影响功能和页面表现,但与 Journey 的结构和接口职责不同。
1.5 后端工程师需要建立的前端认知#
当前工程主要使用 React 18、TypeScript、Webpack 5、SCSS,采用多入口多页面架构。每个页面有自己的入口和 HTML,构建时按应用与市场选择页面集合。
页面可以运行在浏览器或 App WebView 中。项目通过 Bridge 封装页面跳转、返回和其他宿主能力。浏览器能打开页面,并不代表 App 中的返回、登录和支付链路已经验证完成。
| 后端熟悉的概念 | 在本项目前端中如何理解 |
|---|---|
| 服务启动入口 | index.tsx 挂载页面,并进行页面级初始化 |
| 业务用例编排 | App、业务组件和 Hook 组织数据、交互与页面状态 |
| 下游接口客户端 | service/model 调用统一 request,封装接口协议 |
| 请求上下文 | props、state、Context 和持久化缓存有不同生命周期 |
| 配置驱动 | Journey 决定部分页面结构;PFC 提供命中条件下的配置 |
| 日志与调用链 | Network、Console、IDAP 与后端日志结合排查 |
前端组件会随状态变化重复渲染,不能把组件函数当作“只执行一次的服务初始化”。跨页面跳转后,组件状态也不能自然保留,需要明确缓存与参数传递方式。
2. 本地环境:从安装到打开业务页面#
本章按实际准备顺序操作:拿到有效入口与权限 → 安装依赖 → 选择环境并启动 → 配置浏览器代理与 HTTPS → 验证业务域名、接口和登录态。默认先跑通浏览器,模拟器与真机准备放在第 3 章。
2.1 准备入口、账号与权限#
先拿到仓库访问权限,以及一个可以复现的非生产产品入口。开发样例至少要包含:市场、环境、产品、页面 URL、测试账号获取方式,必要时还包括后端 PFB。
需要访问的能力包括公司 npm 源、项目启动所需的 KMS、产品工厂配置、翻译平台,以及联调使用的后端环境。具体权限申请入口由团队维护人提供。
本文示例从已拉取的 nonmotor_h5 仓库根目录执行。开发者可使用自己的 IDE,但终端工作目录必须正确。
2.2 安装 Node 与项目依赖#
仓库 .nvmrc 当前声明 v20。已安装 nvm 的同学可以执行:
nvm install
nvm use
node -v
npm -v使用其他 Node 版本管理器时,同样以项目版本文件为依据。package.json 中较宽泛的最低版本声明,不代表所有更低版本都已验证可用。
部署安装脚本使用以下依赖安装方式,本地可以据此准备依赖:
npm install --registry https://npm.shopee.io --legacy-peer-deps安装失败时,先根据错误区分 npm 源访问、权限、Node 版本和原生依赖编译问题。不要通过随意升级依赖或删除锁文件来跳过原因分析。安装后检查 package-lock.json 差异,确认是否属于本次需求。
2.3 选择环境并启动本地服务#
| 配置 | 作用 | 需要注意 |
|---|---|---|
APP_NAME |
选择应用及入口配置 | 本项目目标服务选择 nonmotor |
REGION |
选择市场入口和区域实现 | 使用目标市场,例如 my、id;并非每个应用都支持菜单中的全部市场 |
ENV |
选择开发/构建环境 | 对应 mock、dev、test、uat、live 等;日常联调选已约定的非生产环境 |
BUILD_ENV |
选择构建环境与相关运行配置 | 按目标业务选择 spin 或 spic |
BROKER_NAME |
部分 spic 场景的主体配置 | 仅按实际业务选择 |
TRANSIFY_REPORT |
本地翻译使用上报开关 | 启动菜单可选择,默认 off |
| 后端 PFB | 指定联调的后端分支环境 | 不等于前端 ENV;必须结合实际请求验证 |
npm run dev 的交互脚本会把所选配置保存到仓库根目录 .env。新任务开始时应核对配置,不要无意复用上一次开发的市场和应用。
npm run start 和 npm run build 都会先执行 scripts/kms.js。KMS 访问失败属于启动前置条件问题,应按团队约定准备对应凭证和网络;凭证不要写进源码、MR 或共享排障日志。
使用交互入口启动#
npm run dev依次选择“开发”、目标环境、Transify 上报设置、目标市场、服务 nonmotor、构建环境;需要时再选择主体。首次启动应显式选择,确认无误后才使用“使用上一个命令”。
脚本随后调用 npm run start。默认端口为 3000,端口变更时以终端输出为准。
2.4 建立浏览器到本地服务的代理链路#
本地联调使用 ZeroOmega 浏览器代理插件 + Whistle 代理服务 + 本地开发服务。三者职责如下:
| 工具 | 职责 | 本文使用的地址 |
|---|---|---|
| Proxy SwitchyOmega 3(ZeroOmega) | 控制 Chrome 请求是否经过指定代理 | 指向 127.0.0.1:8899 |
| Whistle | 抓包、匹配规则、转发或替换请求响应 | 默认代理端口 8899,管理后台为 http://127.0.0.1:8899 |
| nonmotor 开发服务 | 返回本地 HTML、JS/CSS,并通过开发代理处理 /api |
默认 localhost:3000 |
Whistle 是基于 Node.js 的跨平台网络代理与调试工具,支持 macOS、Windows、Linux。日常使用它查看请求、代理页面和接口、mock 响应、模拟弱网以及调试移动端 H5。ZeroOmega 只负责代理选择,安装插件后还需要运行 Whistle。Whistle 项目说明
以 MY Test 的整站代理规则为例:
- Chrome 访问 MY Test 域名
- ZeroOmega
- Whistle 8899
- 本地开发服务 3000
- 返回本地页面与资源
- API 经开发代理发往后端
- 本地开发服务 3000
- Whistle 8899
- ZeroOmega
浏览器地址栏仍是业务域名,本地代码通过代理返回。页面 Cookie 和存储仍按浏览器中的域名使用;代理本身不会创建登录态。
安装 ZeroOmega 插件#
在 Chrome 中打开 Proxy SwitchyOmega 3(ZeroOmega)安装页,安装后进入插件设置,新建一个代理情景模式,例如命名为 Whistle。
| 设置项 | 值 |
|---|---|
| 代理协议 | HTTP |
| 代理服务器 | 127.0.0.1 |
| 端口 | 8899 |
将该 HTTP 代理设为默认代理,使目标 HTTP/HTTPS 请求都经过它;若界面分别配置 HTTP、HTTPS 请求代理,两者均指向上述代理服务。这里选择的 HTTP 是浏览器连接代理的方式,不代表目标业务页面必须使用 HTTP。
保存/应用设置。等 Whistle 启动后,再通过插件图标切换到 Whistle 模式。也可以在自动切换模式中仅让目标业务域名走此代理。
安装并启动 Whistle#
完成 Node 环境准备后,在终端执行:
# 安装命令行版
npm i -g whistle
# 启动并查看状态
w2 start
w2 status打开 Whistle 本地管理后台。主要使用 Network 查看流量,使用 Rules 编辑代理规则。命令行版的常用管理命令如下:官方命令行文档
# 重启
w2 restart
# 停止
w2 stopWhistle 也提供桌面客户端,可从官方安装说明进入;本指南统一以命令行版为例。同一套环境选择一种运行方式,避免两个实例竞争端口或误用另一套规则。
安装证书并开启 HTTPS 抓包#
业务页面使用 HTTPS 时,需要让 Whistle 解密请求,才能按页面路径代理并查看明文请求响应。完成以下设置:
- 在 Whistle 管理界面打开 HTTPS,通过 Download RootCA 下载本机 Whistle 根证书。
- 在操作系统中安装并信任该证书。macOS 可在“钥匙串访问”中导入并设置证书信任;也可使用下面的官方命令完成安装,按系统提示确认。
- 在 Whistle HTTPS 设置中开启 Enable HTTPS (Capture Tunnel Traffic)。
- 重新加载目标 HTTPS 页面,检查是否能看到具体 URL、请求头和响应内容。
w2 ca证书安装与 HTTPS 解密开关需要同时完成。若只看到 Tunnel to 而无法查看目标请求内容,先检查解密开关、证书信任以及请求是否经过当前 Whistle 实例。HTTPS 设置说明、证书安装命令
配置目标市场的代理规则#
在 Whistle 的 Rules 中按市场与环境建立规则组,例如 nonmotor-my-test,粘贴规则、保存并启用。本地 3000 端口一次运行的是当前选择的应用/市场/环境;日常只启用本次需要的规则组。
以 MY Test 为例,团队材料使用整站转发,本指南整理为显式指定 HTTP 目标的写法:
# MY Test:保留请求路径,整站转发到本地开发服务
protection.test.shopee.com.my http://localhost:3000它会将 /nonmotor/purchase5.html?... 转发到本地相同路径。已有整站规则时,指向相同服务、保留相同路径的 /ins、/nonmotor、/common、/ec、/static 规则可合并,避免重复维护。使用 http:// 明确目标是本地 HTTP 开发服务,URL 路径按规则自动拼接。Whistle HTTP 转发规则
整站转发也包含 /api,接口随后由 scripts/start.js 的开发代理决定最终后端目标。因此需要核对浏览器访问环境、Whistle 规则和本地启动环境。它不是只替换 HTML 的规则。
如果只想代理某个页面目录,可以使用下列规则替代整站规则;资源和其他请求的去向需要另外核对,不要与整站规则一起启用后误以为范围已缩小:
# 可选:仅把 nonmotor 路径转发到本地
protection.test.shopee.com.my/nonmotor http://localhost:3000/nonmotor各市场的整站规则见附录 C。代理规则不会自动启动项目,也不会让未构建的应用页面出现:APP_NAME=nonmotor 时,其他应用入口是否可用仍取决于本地构建内容。
2.5 使用有效业务 URL 与登录态#
开发环境生成的 HTML 路径带应用前缀。例如,MY 的 purchase5 在默认端口下对应:
http://localhost:3000/nonmotor/purchase5.html?product_id=<目标产品ID>这是路径示意,<目标产品ID> 必须替换成实际值,其他必要参数应从有效业务入口保留。该页依赖产品配置、登录态和前序流程数据时,应从产品详情进入;直接打开中间页不能替代完整链路验证。
完成第 2 章代理配置后,日常联调在浏览器打开对应环境的原始业务地址,例如 MY Test:
https://protection.test.shopee.com.my/nonmotor/purchase5.html?product_id=<目标产品ID>浏览器通过 Whistle 获取本地页面,地址栏保持 MY Test 域名。直接访问 localhost 可用于检查本地页面服务,但两者的 Cookie/存储域不同,不能把 localhost 能打开视为业务域名登录已完成。
仓库旧 README 中的 /ins/ 和根路径示例不能直接套用到 nonmotor。开发路径依据 config/webpack.config.js,页面名单依据 config/nonmotor/{region}.json。
2.6 核对 API 环境与 PFB#
scripts/start.js 已包含开发代理:非 mock 环境根据 BUILD_ENV、REGION、ENV 等选择后端域名,并代理 /api 请求;mock 环境将 /api 指向本地 3001 端口。
启动后先查看终端输出的请求转发域名,再在浏览器 Network 面板核对具体请求。页面加载成功、代理目标正确、登录成功是三个不同检查点。
使用第 2 章的整站规则时,请求链路是“浏览器 → Whistle → 本地开发服务 → 开发 API 代理”。登录 Cookie 的域、环境和账号必须匹配当前打开的页面;后端使用 PFB 时,验证实际链路是否命中目标 PFB。
用户提供的浏览器域名与当前 scripts/start.js 的部分 API 目标存在差异:
| 市场/环境 | 材料中的浏览器域名 | 当前 spin 开发代理目标 |
|---|---|---|
| TH Test | protection.test.shopee.co.th |
protection.test.moneeinsurebroker.co.th |
| TH UAT | protection.uat.seainsurebroker.co.th |
protection.uat.moneeinsurebroker.co.th |
| SG Test / UAT | test.moneeinsureagency.sg / uat.moneeinsureagency.sg |
test.seainagency.sg / uat.seainagency.sg |
| PH Test / UAT | protection.test.moneeinsurebroker.com.ph / protection.uat.moneeinsurebroker.com.ph |
protection.test.seainsureagency.com.ph / protection.uat.seainsureagency.com.ph |
此表记录材料和源码的差异,不据此认定域名不可用或需要替换。目标环境是否通过别名或迁移实现兼容,需要实际联调确认。浏览器域名正确仍不足以证明 API 目标正确,本次文档整理未修改代理源码。
2.7 首次启动的验收清单#
首次开发不以“终端没有报错”为结束,应完成以下检查:
- Webpack 编译完成,目标
/nonmotor/*.html可以打开。 - 当前应用、市场、环境和产品与需求一致。
- 页面能获取正确 Journey 或业务数据,接口没有登录失败。
- 修改一处目标页面代码后,能够确认浏览器运行的是本地版本。
- 至少完成目标产品的一段真实交互,核对请求和页面结果。
代理链路还应检查:
- ZeroOmega 已选中 Whistle 模式,Whistle Network 中能看到目标请求。
- HTTPS 请求能展开内容,规则已启用,本地服务确实返回目标页面。
- 在业务域名下刷新页面能看到本地改动,API 返回来自预期环境。
- 调试结束后恢复代理设置,浏览器和手机能够正常访问网络。
若 Whistle 看不到请求,先查插件模式和代理端口;能看到请求但页面未替换,查规则命中、缓存和本地路径;接口报登录错误则继续核对账号、Cookie 域和 API 目标,代理工具不会代替登录步骤。
3. 调试方式:浏览器、模拟器与真机#
本章解决“在哪里验证、用什么工具看问题”。第 2 章先跑通请求链路,本章再区分浏览器局部调试、App 内 H5 调试和完整业务自测。
3.1 按任务选择调试环境#
日常开发可以先在浏览器快速调试,再用模拟器检查 App 内行为,提测前优先在真机完成主流程自测。三种方式共享同一套业务代码,但运行环境和可验证的能力不同。
| 方式 | 优势 | 主要限制 | 适合做什么 |
|---|---|---|---|
| iOS 模拟器 | 在电脑上运行 Shopee App,可配合 Safari 调试 App 内 H5 | 占用电脑内存,依赖 Simulator App 构建;不能完全替代真实设备 | H5 与 App 的交互、Bridge 跳转与返回、iOS WebView 问题定位 |
| 浏览器 | 轻量,不用启动模拟器;有有效 URL 和所需登录态即可访问,调试工具使用方便 | 缺少 App 宿主能力,无法走完依赖原生页面的完整下单流程 | 页面布局、DOM、字段校验、接口数据、异常状态和快速修改验证 |
| 真机 | 最接近用户实际的触摸、输入、滚动和 App 使用体验 | 需要目标设备、App、测试账号及网络环境 | 业务主流程自测首选,尤其是支付、OTP、地址选择和跨页面返回 |
3.2 浏览器:日常开发与局部验证#
浏览器调试最轻量。完成代理和登录准备后,直接打开目标业务 URL,使用 Chrome DevTools 的 Elements、Console、Network、Sources、Application 等面板即可调试,不必同时运行模拟器。

图示:完成登录鉴权后,通过有效的业务 URL 打开 H5 页面;Console 查看日志,Network 查看请求,Elements 检查 DOM 与样式,Application 查看当前域名的 Local Storage、Session Storage 和 Cookie。截图中的 URL 和参数仅用于说明入口位置,实际调试请使用本次产品的有效入口。点击图片可放大查看。
适合先完成布局调整、文案检查、字段校验、接口响应处理等工作。浏览器的设备模拟模式可以辅助检查移动端尺寸,但页面仍运行在浏览器环境中,不会因此获得 Shopee App 的 Bridge、RN 或原生能力。
当前项目涉及 App 能力的完整下单流程,不能只在普通浏览器中验收。 按团队提供的场景,支付页面、OTP 验证页面、SP 统一的 address select 页面等需要跳转到 App 内的 RN/原生页面,浏览器无法复现这些跳转及返回链路。具体页面承载方式以目标市场和 App 版本为准。
遇到这些边界时,转到模拟器或真机继续验证。即使使用 mock 或模拟 Bridge 返回值,也只说明 H5 在指定返回数据下的处理正常,不能证明真实 App 跳转、回调和下单流程通过。
3.3 模拟器:安装 App 并配置代理#
本节适用于 macOS + Xcode 的 iOS 模拟器,用于验证 Shopee App 内的 H5 展示、返回与 Bridge 交互。安装入口和内部 App 下载方式来自团队提供的截图;截图中的设备、iOS 和 App 版本只是示例,选择时以当前测试要求和兼容性为准。
第一步:安装 Xcode 并启动模拟器#
- 从团队材料中的 Xcode 下载目录获取适配当前 Mac 的 Xcode,完成安装及首次启动要求的组件安装。
- 在 Xcode 中确认已安装目标 iOS Simulator runtime。如果没有可选的 iOS 设备,先在 Xcode 设置的运行时/组件管理界面下载所需版本;不同 Xcode 版本的菜单名称可能不同。Apple 运行时安装说明
- 搜索并打开
Simulator.app,或通过 Xcode 的 Open Developer Tool → Simulator 打开。 - 选择并启动一个目标 iPhone 模拟设备,等待进入 iOS 主屏幕。
Simulator 是 Xcode 自带的开发工具。仅有命令行工具不等于已经准备好完整的模拟器环境。Apple Simulator 说明
第二步:下载对应市场的 Simulator App 包#
进入团队 App 平台 app.sea.com,选择需要调试的 Shopee 市场 App。截图给出的示例为 Shopee ID App 页面,其他市场选择各自对应的 App。
在 iOS 版本列表中搜索 simula 或 simulator,找到团队要求的模拟器构建版本并下载。不要把截图中的历史版本号作为统一安装要求;也不要仅凭市场一致就选择任意 Native Feature Build,应使用本次测试约定的构建。
安装包需要明确支持 iOS Simulator,并与当前 Mac 架构及模拟器运行时兼容。普通真机安装包不能通过改扩展名变成 Simulator 包。
第三步:解压并安装 App#
- 若下载的是可直接使用的
.app应用包,直接进入安装步骤。 - 若是压缩包,先解压。团队材料中的“改后缀为
.zip”适用于内容本身为 ZIP 归档、但下载扩展名不便解压的包;已经是.zip的文件直接解压即可。 - 在解压目录中找到
.app应用包,将它拖到已经启动的 Simulator 设备窗口中安装。 - 等待主屏幕出现 App 图标,打开并检查能否正常启动。
如果安装失败,先核对是否误下真机包、市场/构建是否正确、Mac 架构及 runtime 是否兼容。App 安装完成后,再按团队测试账号流程登录;账号获取和登录操作另行补充。
第四步:为模拟器开启系统代理#
第 2.4 节的 ZeroOmega 控制 Chrome 请求,不能代替模拟器 App 的代理设置。按团队材料,模拟器联调通过 Whistle 设置 Mac 系统代理:
# 启动 Whistle
w2 start
# 设置 Mac 系统代理,指向运行中的 Whistle
w2 proxy默认 Whistle 使用 127.0.0.1:8899。开启系统代理会影响使用该系统代理的其他应用,操作前保留原代理配置,结束后恢复。Whistle 系统代理命令
同时完成以下配置:
- 在 Whistle 启用目标市场/环境的规则组,启动对应的 nonmotor 本地服务。
- 在 Whistle 开启 HTTPS 解密,并在当前模拟设备内安装、信任该实例的根证书。可以通过模拟器 Safari 打开 Whistle 证书下载地址,再按 iOS 的描述文件安装与证书信任流程操作;不要仅凭 Mac 已信任证书就认定模拟器也已完成配置。iOS 的信任步骤见Whistle 移动端证书说明。
- 先在模拟器 Safari 打开目标 HTTPS 页面验证网络与证书,再在 Shopee App 中从实际业务入口打开目标 H5,验证 App 内行为。
浏览器 ZeroOmega、Mac 系统代理和实体手机 Wi-Fi 代理是不同的流量入口,按调试设备选择;三者可以指向同一个 Whistle 服务。
第五步:验证并结束调试#
在 Whistle Network 中观察请求,并核对:
| 检查项 | 通过标准 |
|---|---|
| 模拟设备 | 能进入 iOS 主屏幕,目标 App 能正常启动 |
| 代理 | 模拟器访问目标页面时,Whistle 能捕获对应请求 |
| HTTPS | 能查看具体请求与响应内容,无证书信任错误 |
| 页面版本 | 目标业务域名返回本地修改后的页面 |
| 业务链路 | 登录、接口环境、页面返回与相关 Bridge 行为符合本次需求 |
若 Safari 请求可抓取、但目标 App 请求不可抓取,应继续检查 App 的网络及证书策略,不把浏览器验证结果当作 App 已通过。模拟器用于日常开发验证,依赖真实设备能力的场景仍需按验收要求在真机验证。
调试结束,或其他软件因系统代理出现网络问题时,关闭本次启用的系统代理:
w2 proxy 0
# 不再需要 Whistle 时再停止服务
w2 stop截图使用 w2 proxy off,本文统一采用官方当前文档列出的 w2 proxy 0。若原来已有公司代理或其他网络工具,应恢复原设置;Chrome 的 ZeroOmega 若仍选着 Whistle 模式,也需要切回正常模式。Whistle 命令说明
团队安装材料截图#

截图中的内部下载地址作为团队提供的安装入口保留,本次未登录这些平台确认可下载版本,也未实际安装 Xcode、App、证书或修改系统代理。
3.4 Safari:检查 App 内的 H5#
模拟器负责运行 App,Mac 上的 Safari Web Inspector 负责查看和调试其中的 H5。可以把它理解为“给模拟器里的网页打开 F12”。
- 打开 Mac 上的 Safari → Settings(设置)→ Advanced(高级),勾选 Show features for web developers(显示网页开发者功能)。旧版 Safari 的文案可能为“在菜单栏中显示开发菜单”。
- 启动 iOS 模拟器,在 Shopee App 中进入要调试的 H5 页面,保持页面打开。
- 在 Mac Safari 的 Develop(开发) 菜单中,找到正在运行的模拟设备,再选择对应 App 下的目标 H5 标题或 URL,打开 Web Inspector。
- 在模拟器中操作页面,同时在 Mac 上查看日志、请求、DOM 与样式。页面跳到新 WebView 后,必要时重新选择当前页面。

图示:Safari → Develop → 当前模拟器或真机 → Shopee → 目标 H5 页面。截图中选中的是已连接的真机,模拟器入口位于同一菜单;选择页面后会打开下方的 Web Inspector。点击图片可放大查看。
模拟器的远程检查能力默认开启,无需照搬真机的 Web Inspector 开关步骤。菜单中能否出现具体 App 页面,还取决于该 App 构建是否允许检查 WebView。WebKit 启用 Web Inspector 说明
| 想查什么 | 使用的面板/能力 | Nonmotor 中的例子 |
|---|---|---|
| 打印的 Log、JS 错误 | Console | 查看初始化异常、字段联动日志和 Bridge 调用前后的输出 |
| 请求及响应 | Network | 核对接口参数、业务码、响应内容与耗时 |
| DOM 节点和样式 | Elements / Styles | 找到实际渲染的节点,检查显隐、间距、遮挡和滚动布局 |
| 登录及页面存储 | Storage / Cookies 等相关面板 | 核对当前域名的 Cookie、localStorage、sessionStorage;排查回退后旧数据或字段丢失 |
| JS 执行过程 | Sources / Debugger | 设置断点,检查用户输入如何进入缓存和请求参数 |
这里的“缓存”需要分清:表单数据可能在页面存储中,JS/CSS 等资源还可能命中 HTTP 缓存。先核对当前页面和数据来源,再决定清理哪一项;清理存储可能同时清掉登录态或前序投保信息。
如果 Develop 中没有目标页面,先确认 App 已打开 H5、选对设备和页面,再核对测试包是否开放 WebView 检查。能检查模拟器 Safari 中的网页,不代表一定能检查 Shopee App 内的 WebView;需要时由客户端同学确认构建配置。WebKit App 内容检查说明
Safari Web Inspector 主要检查选中的 H5 页面;Whistle 用于观察经过代理的网络流量和执行转发规则。两者配合使用。Safari 的 DOM/样式面板不能直接检查 App 的 RN 或原生页面内部实现。
3.5 真机:验证完整用户交互#
可以直观理解为“把电脑里的模拟设备换成手里的真实手机”。真机能更接近用户实际操作,尤其适合检查触摸、键盘遮挡、滚动、返回手势和 App 页面切换。提测前优先使用真机完成本次需求的主流程自测。
使用目标市场、环境和测试版本的 Shopee App,从实际业务入口进入页面。调试本地代码时,按第 3.6 节配置手机代理及证书,并确认手机请求确实经过电脑上的 Whistle。
需要检查 iPhone 内的 H5 时,在 iPhone 设置中找到 Safari → Advanced(高级)→ Web Inspector(网页检查器),开启后连接 Mac 并完成设备信任,再从 Mac Safari 的 Develop 菜单选择该设备与可检查的 H5;较新 iOS 的 Safari 设置可能位于“设置 → App”内。此方式同样要求 App 开放对应 WebView 检查。iOS 远程检查说明
自测重点包括:
- 从入口到目标页面、字段输入、确认和下单的完整链路,包含本次涉及的支付、OTP、地址选择及其返回结果。
- 弹出键盘后输入框和底部按钮是否可见,长页面是否能正常滚动,触摸和返回手势是否符合预期。
- 返回修改、取消操作、重新进入、切到后台再回来时,页面状态和数据是否正确。
- 本次影响的目标系统、App 版本和市场。只在一台 iPhone 上通过,不代表 Android 或其他 App 版本也已通过。
给 QA 的自测记录应写清设备/系统、App 版本、市场、环境、入口、执行场景和结果,区分浏览器验证、模拟器验证与真机验证。
3.6 Whistle 联调能力与代理收尾#
| 场景 | 用法 |
|---|---|
| 查看接口 | 在 Network 中查看 URL、请求/响应头、响应体和耗时 |
| 临时 mock | 用限定范围的规则替换目标接口响应,模拟特定数据和错误 |
| 弱网验证 | 用延迟、限速规则检查 loading、超时与重试表现 |
| 页面远程调试 | 按需使用 Whistle 内置 Weinre、Console 能力 |
这些能力可以在不修改业务代码的情况下调整网络行为,规则使用后应关闭,避免影响下一轮真实接口验证。Whistle 快速上手
手机代理与证书#
手机调试时,手机与电脑需网络互通;将手机 Wi-Fi 的手动代理设为电脑的局域网 IP + 8899,不能填写手机自己的 127.0.0.1。手机也需要安装并信任该 Whistle 根证书,iOS 安装描述文件后还需开启完全信任。部分 App 的证书策略可能限制抓包,应以实际运行结果为准。移动端抓包说明
结束调试时,先将 ZeroOmega 切回原先的正常模式,再按需执行 w2 stop;手机或系统若设置了手动代理,也应恢复原配置。本文浏览器方案不要求同时开启系统代理,只有配置过的代理入口才需要恢复。
4. 代码定位:从业务 URL 找到实现#
本章的目标是找到“当前产品真正执行的代码”。按应用与市场确认入口,再沿 index.tsx → App.tsx → model/组件/Hook 阅读;找到同名文件还不足以证明定位正确。
4.1 常用目录#
| 目录或文件 | 主要职责 |
|---|---|
config/nonmotor/{region}.json |
nonmotor 各市场的 entry 和 HTML 配置 |
config/bizConfig.js |
根据 APP_NAME、REGION 读取并组装入口配置 |
src/pages/ |
页面实现,包含历史页面、市场页面和工厂页面 |
src/pages/factory/、src/pages/factoryV2/ |
产品工厂页面、组件、解析和业务实现 |
src/pages/checkoutV2/ |
收银台页面及相关业务代码 |
src/service/ |
按领域组织的接口封装 |
页面内的 model/、service/ |
部分既有页面的请求与数据处理,阅读时沿实际 import 查找 |
src/common/request.ts |
请求、登录检测、签名等公共行为 |
src/InsEntry/ |
动态表单、字段组件和校验能力 |
src/MoneeDesign/ |
基础 UI 控件、图标及样式能力 |
src/components/ |
共享组件和业务组件 |
src/module/ |
URL、存储、日期、Cookie 等公共工具 |
src/bridge/ |
App 宿主交互封装 |
src/locales/ |
文案格式化与翻译读取 |
runbooks/、docs/automation/ |
回归用例与 UI 自动化规范 |
deploy/ |
安装、构建和部署配置 |
仓库保留了 ins_h5 的名称、工具和其他业务源码。判断一个页面是否属于当前 nonmotor 构建,要查入口配置,不能仅靠目录名或文件是否存在。
先分清应用配置、市场和维护仓库#
第 4.2 节截图左侧的目录按应用划分页面注册,目录内的 my.json、sg.json 等再按市场划分。拿到需求后,先确认应用与市场,再查页面文件名。 对后端同学而言,可以把这些 JSON 理解为构建时的“页面入口清单”:它决定本次构建包含哪些页面及其源码入口,业务内容仍由页面代码、接口和配置决定。
| 配置目录 | 对应应用与页面路径 | 页面范围与查找方式 |
|---|---|---|
config/nonmotor/{region}.json |
APP_NAME=nonmotor,/nonmotor/*.html |
当前非车险应用的入口清单,本指南主要在这里定位页面 |
config/bizConfig/{region}.json |
APP_NAME=ins,/ins/*.html |
截图标注的 motor 页面所在配置;当前仍保留部分历史工厂/非车险入口,不能将其理解为“只含 motor” |
config/common/{region}.json |
APP_NAME=common,/common/*.html |
公共应用页面;例如 MY 配置中的 home.html、product-list.html、policy-list.html |
config/ec/{region}.json |
APP_NAME=ec,/ec/*.html |
EC 应用页面;例如 MY 配置中的 ec-pdp.html,按目标页面继续查注册 |
按团队截图中的维护约定,common 应用页面的需求在 ins_h5 仓库修改;nonmotor 应用页面在 nonmotor_h5 仓库处理。 两个仓库中都可能保留相似目录,不能因为当前仓库里搜到了文件,就认为应该在这里提交需求。
还要区分两种 common:config/common/ 表示 common 应用的页面清单,src/pages/common/ 只是源码目录。例如 MY nonmotor 的 area-selector.html 指向 src/pages/common/areaSelector/index.tsx,它仍是注册在 nonmotor 应用下的页面。源码路径、构建归属和维护仓库需要分别确认。
4.2 页面介绍:从 URL 找到入口和实现#

图示以 config/nonmotor/my.json 的 factory-pdp6 为例:左侧是应用与市场配置,中间的 entry 关联入口名和源码,右侧的 htmlPlugin 将 HTML 文件与入口关联。点击图片可放大查看。
读懂 entry、chunks 与 filename#
下面摘取当前配置中的 PDP6 注册项,省略同文件中的其他页面:
{
"entry": {
"factory-pdp6": "factoryV2/pdp/index.tsx"
},
"htmlPlugin": [
{
"inject": true,
"templateKey": "appHtml",
"chunks": ["factory-pdp6"],
"filename": "factory-pdp6.html"
}
]
}| 配置项 | 在本例中的含义 | 开发时怎么用 |
|---|---|---|
entry 的 key:factory-pdp6 |
页面打包入口名,与截图中的 chunk 名对应 | 用它关联 htmlPlugin.chunks,不是直接访问的 URL |
entry 的 value:factoryV2/pdp/index.tsx |
相对于 src/pages/ 的入口源码路径 |
实际打开 src/pages/factoryV2/pdp/index.tsx |
chunks: ["factory-pdp6"] |
该 HTML 关联的入口 | 必须能在 entry 中找到对应 key |
filename: "factory-pdp6.html" |
生成的页面文件名 | 用浏览器 URL 中的 HTML 文件名反查它 |
templateKey: "appHtml" |
HTML 模板标识 | config/paths.js 将它映射到 public/index.html,并非业务 React 页面 |
inject: true |
让 HTML 插件注入构建资源 | 不需要手工把每个打包脚本写进页面模板 |
这里区分的是入口名、源码路径、页面文件名三个概念,它们不必同名。例如 confirm-info3.html 对应的 chunk 是 factoryV2ConfirmInfo,源码位于 factoryV2/confirmInfo/index.tsx。构建还有公共依赖拆分,不能据此推断一个 HTML 只加载一个 JS 文件。
用截图中的 PDP6 走一遍定位过程#
假设已经确认目标是 MY 市场、nonmotor 应用,页面路径为 /nonmotor/factory-pdp6.html:
目标市场 MY + /nonmotor/factory-pdp6.html
→ config/nonmotor/my.json
→ htmlPlugin.filename: factory-pdp6.html
→ htmlPlugin.chunks: factory-pdp6
→ entry["factory-pdp6"]: factoryV2/pdp/index.tsx
→ src/pages/factoryV2/pdp/index.tsx
→ 同目录 App.tsx
→ Journey 请求、区块组件、表单与业务逻辑市场不能只靠 /nonmotor/ 判断,要结合业务域名、需求和启动配置。前面浏览器截图使用的是 SG 域名,实际定位该页面时应查 config/nonmotor/sg.json;当前 SG 的 PDP6 也指向同一源码,但不能因此假定所有页面在每个市场都已注册。
继续阅读源码时,按职责分层:
- 页面启动:
src/pages/factoryV2/pdp/index.tsx。 创建 React 根节点,执行JS_START、trackAutoExpo('insurance_product')等初始化,通过BaseComponent挂载App,并声明必需参数product_id。 - 页面编排:同目录
App.tsx。 创建 Form 和页面状态;普通业务入口默认调用queryFactoryProductDetail('pdp')获取页面数据。源码也支持queryPageData的定制分支和 Admin 预览,阅读具体产品时继续核对实际分支。 - 请求与解析:
src/pages/factoryV2/model/queryProductFactoryJourney.ts。 默认请求封装读取 URL 中的product_id,调用 Journey 接口,再通过parseFactoryProductDetail选择pdp页面并解析配置。源码请求路径还可能被公共请求层按迁移配置改写,最终以 Network 为准。 - 区块与交互:
pdp/syncComponents/、factoryV2/hooks/useGenerateComponents及相关业务组件。App.tsx将解析后的页面数据交给组件生成逻辑;样式、表单、试算、底部购买按钮等继续沿对应组件与 Hook 查找。
同一个 factory-pdp6.html 可以承载不同产品。HTML 文件名帮助定位页面模板,product_id、Journey 和接口数据决定当前展示的具体业务。因此,定位到 App.tsx 只是找到入口,还要确认当前产品实际加载的区块和字段。
常见页面的注册对照#
以下映射均来自当前 config/nonmotor/my.json。源码列统一相对于 src/pages/,具体产品不一定经过全部页面,也不保证按表格顺序跳转。
| 页面文件名 | 主要用途 | chunk / entry key | 入口源码 |
|---|---|---|---|
factory-pdp6.html |
产品详情、方案与报价展示、投保入口 | factory-pdp6 |
factoryV2/pdp/index.tsx |
purchase5.html |
投保信息录入与步骤处理 | purchase5 |
factoryV2/purchase5/index.tsx |
confirm-info3.html |
投保信息确认 | factoryV2ConfirmInfo |
factoryV2/confirmInfo/index.tsx |
checkout.html |
收银台及后续支付衔接 | checkout |
checkoutV2/index.tsx |
area-selector.html |
地区选择辅助页 | areaSelector |
common/areaSelector/index.tsx |
用同样的方法可以定位 MY 投保信息页:purchase5.html → purchase5 → src/pages/factoryV2/purchase5/index.tsx → App.tsx。该页调用 queryFactoryProductDetail('purchase', true),但其 import 指向 src/pages/factory/model/queryProductFactoryJourney.ts,与上述 PDP6 使用的 factoryV2/model 不同。跟随当前文件的实际 import,不凭相似目录名选择实现。
常用搜索命令:
# 先在目标市场的入口配置中查页面文件名
rg -n 'factory-pdp6.html|factory-pdp6|purchase5' config/nonmotor/my.json
# 再追踪页面请求与组件生成逻辑
rg -n 'queryFactoryProductDetail|useGenerateComponents' src/pages/factoryV2/pdp
rg -n 'query_product_factory_journey' src/pages/factoryV2/model/queryProductFactoryJourney.ts
# 修改共享源码前,检查哪些应用、市场还引用它
rg -n 'factoryV2/pdp/index.tsx' config配置如何变成可访问页面#
config/bizConfig.js 根据 APP_NAME 和 REGION 选择 JSON,将 entry 中的相对路径解析到 src/pages/,并解析 HTML 模板。config/webpack.config.js 为各项创建 HTML 插件,本地开发时加上应用前缀,例如 /nonmotor/factory-pdp6.html;生产构建的输出目录由 config/paths.js 决定,nonmotor 对应 dist/nonmotor。
这解释了三个常见问题:只有源码文件、没有入口注册,页面不会自动进入该市场构建;注册了 MY 页面,不代表 SG 页面同时可用;修改入口配置后,需要重启开发服务让新的入口清单生效。对已存在的共享页面做改动,还要检查其他应用、市场和产品的影响范围。
4.3 阅读旧代码与编写新代码的区别#
历史页面可能存在不同目录布局、旧接口封装或宽泛类型。阅读时跟随真实调用链;新增代码时遵守当前项目规范,复用既有工具,并保持本次改动范围清晰。
例如,公共 API 通常放在 src/service/{domain};维护一个已有页面时,不应仅为统一目录把整页 model 全部搬迁。
5. 需求分析:确定改动范围与实现方案#
开发按以下顺序推进,每一步都留下一份可检查的结果。
| 阶段 | 要做的事 | 产出/阅读位置 |
|---|---|---|
| 接需求 | 对齐业务场景、页面、状态和接口 | 本章:影响清单与配置/代码判断 |
| 定方案 | 确认复用能力、字段数据流和跨市场影响 | 本章与第 6—7 章:简明方案或 TD |
| 实现 | 修改配置/代码,闭合输入到请求的数据流 | 第 8 章:贯穿练习 |
| 验证 | 联调、异常与返回路径、受影响范围回归 | 第 9 章:验证记录 |
| 交付 | Review、MR、提测、发布物料与部署验收 | 第 10、12 章:交付清单 |
5.1 第一步:把业务需求变成前端影响清单#
编码前,先确认以下信息:
| 维度 | 要明确的问题 |
|---|---|
| 范围 | 哪个市场、产品、渠道、App/浏览器场景?哪些不受影响? |
| 页面 | 从哪里进入?经过哪些页面?返回、刷新、重新进入如何表现? |
| 设计 | 默认、加载、空数据、错误、禁用状态如何展示? |
| 数据 | 来源是接口、Journey、PFC、缓存还是用户输入? |
| 契约 | 字段类型、枚举、空值、业务码、时间和金额口径是什么? |
| 配置 | 是否修改 Journey、翻译、图片、开关或准入配置? |
| 验收 | 正常路径、异常路径、埋点和关联产品如何验证? |
接口有某个字段,并不意味着前端该直接展示或提交它。要同时确定展示规则、交互规则和业务含义。
5.2 第二步:判断修改配置还是代码#
| 需求情况 | 优先处理方式 |
|---|---|
| 已有字段的文案、显隐、支持范围内的校验调整 | 核对 Journey/i18n 和组件能力,优先配置 |
| 现有组件已有能力,但当前产品尚未启用 | 配置接入并验证数据契约 |
| 现有组件缺少交互或展示能力 | 评估扩展现有组件,列出其他调用方 |
| 独立业务区块 | 复用基础控件,新增或调整业务组件及配置接入 |
| 新页面或流程步骤 | 先评估现有模板,再处理入口、导航、缓存和埋点 |
| 接口新增或变更字段 | 对齐类型、请求映射、响应处理和全部消费方 |
如果需求只涉及 Journey,也要验证运行时页面和接口行为;如果修改公共组件,回归范围要覆盖复用方。
5.3 第三步:形成方案并开始开发#
小需求可以用一份简明方案说明目标页面、字段映射、改动文件和验收场景。复杂需求需要 TD,把页面、组件、接口、配置、缓存和发布依赖拆清楚。
开发顺序建议为:确认契约 → 获取当前配置 → 选择复用能力 → 实现页面与数据流 → 联调 → 自测 → Review → 提测。接口尚未就绪时,可以用明确契约的 mock 并行开发,真实接口就绪后补齐联调。
5.4 在对应迭代分支开展工作#
团队在 Casement 中建立迭代,迭代分支命名为 release-v1.x.xxx;本地开发分支命名为 dev-v1.x.xxx,版本号与目标迭代保持一致。例如,release-v1.3.318 对应 dev-v1.3.318。
| 分支 | 用途 | 代码流向 |
|---|---|---|
dev-v1.x.xxx |
开发者本地开发、提交 commit 和自测 | 自测完成后发起 MR,合入对应 release 分支 |
release-v1.x.xxx |
汇集当前迭代的改动,供版本发布与部署使用 | 合入并发布后,在 Casement 部署对应版本 |
完整流程如下:
- Casement 建立 release 迭代
- dev 分支开发与提交 commit
- 本地自测完成
- 提交 MR:dev → release
- MR 合入 release 并发布
- Casement 部署对应版本
- 检查部署结果与页面行为
- Casement 部署对应版本
- MR 合入 release 并发布
- 提交 MR:dev → release
- 本地自测完成
- dev 分支开发与提交 commit
开始修改前检查工作区和当前分支,确认本次需求所属的迭代:
git status --short
git branch --show-current在对应的 dev-v1.x.xxx 分支完成开发和 commit,本地开发、自测完成后推送分支并提交 MR。MR 的 source 选择 dev-v1.x.xxx,target 选择同版本的 release-v1.x.xxx。
提交 MR 前同步目标分支并处理冲突,不把无关工作区变更混入本次需求。确认 MR 已成功合入 release 并完成发布后,再进入 Casement 部署;只有本地 commit 或 MR 尚未合入时,release 版本还不包含本次改动。
Reviewer、审批要求及多人同时使用开发分支时的远端协作约定,按团队安排执行,具体规则待补充。
6. 核心机制:Journey、模板与字段数据流#
本章解释配置如何成为页面,以及页面字段怎样成为后端请求。判断“只改配置是否足够”时,要同时核对组件能力和字段消费链路。
6.1 Journey 的三层结构#
| 层次 | 含义 | 阅读重点 |
|---|---|---|
| page | 一个页面或配置中的页面节点 | 页面名、步骤、页面属性 |
| block | 页面中的业务区块 | 组件名、所在步骤、区块属性和字段集合 |
| entry | 区块中的字段或渲染元素 | component_name、field_name、props、依赖和约束 |
可以将其理解为“配置描述界面需要什么,代码提供可执行的组件能力”。配置写入了某个 component_name,还需要确认目标页面能够解析并加载该组件。
6.2 模板如何解析并渲染 Journey#
这里说的是前端把 Journey 结构解析并映射成 React 组件的运行机制。它包括页面容器、Journey 解析、区块组件注册、动态表单、步骤与路由处理;与 Webpack 生成 HTML 使用的 templateKey: appHtml 分属不同层次。

图 3:产品工厂描述页面需要什么,前端代码实现这些能力,接口提供业务数据与校验结果。不同模板版本的实现路径略有不同。
用 PDP6 和 Purchase5 可以看到完整机制:
- 确认产品和页面。 URL 中的
product_id标识产品;PDP6 默认调用queryFactoryProductDetail('pdp')获取对应 Journey,Purchase5 调用queryFactoryProductDetail('purchase', true)。同一个 HTML 可以服务不同产品。 - 解析页面配置。
parseFactoryProductDetail从pages中取出对应页面,把页面/区块的 props、字段的field_name、dependencies、constraints 等转换成前端消费的数据。 - 生成业务区块。 PDP6 的
useGenerateComponents遍历blocks,根据component_name(兼容name)查找同步注册的组件,或加载对应异步组件。例如 Header、Coverage2、FillInfo、FAQ 都是已经实现的 React 能力。 - 生成字段并执行交互。 FillInfo 等区块继续消费 entries,结合
InsEntry表单能力处理输入、字段值、联动与校验。Journey 描述选用哪些字段和规则,组件代码负责执行;配置里写一个名字,并不会自动生成尚未实现的新功能。 - 编排步骤和下一页。 Purchase5 根据
stepItems建立步骤,并通过区块的forkey归入对应步骤,由PurchaseStepBar控制前进和返回。next_route等配置参与跨页面导航;一个 HTML 内也可能包含多个投保步骤。 - 闭合业务数据。 输入需要按实现完成校验、转换和缓存写回,供确认页与 Checkout 消费;页面能显示字段,并不代表后端已经能收到它。
PDP6 使用 factoryV2/model/queryProductFactoryJourney.ts 和 Factory V2 的生成 Hook;Purchase5、Confirmation 中仍有对 factory/model 或 factory/hooks 的引用。新旧实现共存,定位时应跟随实际 import,而不是根据文件夹名猜测。
Purchase5 在解析 Journey 时传入 true,entry 的运行时 name 使用 field_name。排查联动时应核对表单实际标识,而不只看 Admin 中的 entry 名称。
6.3 配置源与本地 mock#
当前项目约定:
- Admin/O 端
UserJourney_*.json是配置事实来源。 - 对应的
*.admin.journey.view.ts从配置源生成,用于可读性 Review 和本地 mock。 - 本地 Journey mock 从 view 生成,避免再维护一份独立响应快照。
- O 端配置声明 external dependency 的类型和 parser;模拟后端补充的依赖数据留在本地 mock 层。
修改 Journey 时要同步源配置和生成的 view。找不到当前产品的配置时,应先取得有效配置来源,不能根据页面外观拼出一份“看起来合理”的配置。
图片使用经过指定上传流程得到的 CDN 地址;不把 Figma 临时链接或本地路径当作正式 Journey 图片。产品差异优先通过配置表达,配置确实不能承接时再说明代码适配的原因与范围。
6.4 数据闭环要在当前步骤完成#
新增字段时,至少追踪:输入值 → 校验结果 → 缓存位置 → 下游读取 → 展示值 → 请求值。
每个步骤负责把自己的输出处理成下游可直接消费的结构。不要把前序步骤遗漏的字段转换、默认值和业务规则统一堆到最后创单时补救。
项目已有存储工具和 Road Cache helper。阅读具体产品时还要核对缓存 key 与产品、流程、续保等参数的关系。返回修改、切换产品和重新进入,都可能暴露只验证单次向前流程时发现不了的问题。
7. 开发约定:页面、组件、接口与公共能力#
实现前先查已有能力,开发时按职责分层。以下是入门必须遵守的边界,完整规范以仓库 AGENTS.md 和本地 Skills 为准。
7.1 页面与组件如何分工#
| 层次 | 应承担的职责 |
|---|---|
| 页面入口 index.tsx | 挂载页面、页面级埋点及初始化 |
| App / 页面业务层 | 页面数据、状态组合、业务交互与流程 |
| 业务组件 | 一个可独立理解的业务区块及其交互 |
| 基础控件 | 输入、按钮、图标、状态 UI 等通用表现 |
| service/model | 接口类型、参数映射和数据处理;新 Service 不承载 Toast、跳转或 React 逻辑 |
新增基础 UI 优先查 src/MoneeDesign/;新增业务能力先查已有组件。复杂页面可以使用 reducer 和 Context,局部状态尽量留在负责它的组件中,不为一个小需求引入新的全局状态库。
7.2 新建页面的入口注册#
nonmotor 新页面应注册在 config/nonmotor/{region}.json,其中 entry 路径相对 src/pages,htmlPlugin 的 chunks 必须对应 entry key。涉及多个市场时逐个核对目标市场的配置,修改入口后重启开发服务。
现有 npm run template 页面模板脚本仍向 config/bizConfig/{country}.json 写入注册。 使用它生成文件后,必须检查并调整 nonmotor 的入口归属,避免页面建好了却未进入目标构建,或把页面误加到其他应用。
7.3 接口调用#
统一使用 @/common/request,沿用项目登录、签名等公共行为,不在页面中直接另起 axios/fetch 调用业务接口。
前后端联调时逐项确认:请求 URL、HTTP 方法、字段名称与类型、业务成功码、可选字段、错误处理。HTTP 200 与业务成功是不同条件;errFirst 等封装选项也会影响调用方如何接收结果,阅读时以实际调用契约为准。
金额、日期、证件和较长 ID 的转换优先使用已有工具及协议。产品/Journey 等大整数 ID 不能随意转换为 JavaScript Number。若后续生成 API 代码,遵循项目规范中对生成目录的约束,通过生成流程更新,不手工修改生成结果;当前工作区未包含 src/api/ 目录。
7.4 文案、样式与跳转#
- 代码中的用户可见文案通过
formatMsg读取,Journey 下发文案按其 i18n 配置维护。新增 key 要核对目标语言和插值参数。 - 样式采用项目的 SCSS、局部样式和 BEM 约定;项目已配置 px2rem,避免再手工重复换算。
- 按设计稿验证间距、长文案、多语言、滚动、键盘和底部按钮等行为,不能只检查一个桌面窗口下的截图。
- 内部页面跳转使用
@/bridge封装;callWebview/callWebviewUrl的内部 URL 经transformUrl处理,保留产品与来源等公共参数。 - 返回要考虑当前步骤、缓存以及 WebView 生命周期,直接关闭页面不一定等于业务要求的“上一步”。
7.5 nonmotor 迁移相关行为#
src/common/nonmotor.ts 根据 nonmotorMigration 配置处理部分旧页面及 API 地址:pages/force_pages 控制页面迁移,apis 控制指定 standalone API 的迁移。API 改写在统一 request 中调用。
因此排查“源码里是旧地址,Network 里是新地址”时,应同时检查迁移配置。不要把所有 /ins/ 或 standalone URL 全局替换成 nonmotor,也不要假定所有旧地址都会自动迁移。
7.6 埋点和监控#
新增或改变交互时,核对页面、点击和一级业务模块曝光。页面入口负责初始化,事件名称按已确认的 TMS 定义,避免重复上报公共字段或在重复渲染时反复曝光。
性能链路按项目约定覆盖 JS_START、BEFORE_MAIN、AFTER_MAIN、RENDER。业务异常使用带稳定 unique_key 的日志,记录定位所需上下文,避免静默吞错或记录凭证、敏感表单原文。
8. 贯穿案例:给投保流程增加联系邮箱#
本节是教学需求,帮助理解实施过程,不代表某个线上产品已有该需求。真实产品 ID、字段路径、文案 key 和接口应在实施时从配置与协议确认。
练习顺序:补全需求 → 定位页面与配置 → 建立字段映射 → 实现与联调 → 验证返回和异常路径。完成后应交付配置/代码差异、字段映射表、请求证据和自测结果。
8.1 把一句需求写完整#
假设需求为:用户在投保信息页填写联系邮箱;该字段必填,格式不正确时提示;确认页展示邮箱;返回修改后保留最新值;提交时传递给后端。
先确认联系邮箱属于投保人还是其他对象,是否已有接口字段、是否自动预填、能否编辑,以及服务端错误如何反馈。如果这些含义没有确认,先不要用另一个产品的字段路径代替。
8.2 定位页面和已有能力#
从有效 URL 确定市场、产品和页面,按第 4 章定位入口;获取当前产品 Journey,找到目标步骤和字段区块。
仓库已有 src/InsEntry/validate/email.ts,可以检查现有邮箱校验的适用性。同时查看当前产品所用输入组件和约束注册方式。新增字段不等于新增一个输入框组件,也不等于必须改动公共校验。
8.3 建立字段映射表#
| 项目 | 本次必须确认的内容 |
|---|---|
| 展示 | 标签、占位文案、错误文案及对应翻译 |
| Journey | 所属 page/block、entry 标识、component_name、field_name |
| 数据来源 | 用户输入,是否由已有接口或缓存预填 |
| 校验 | 必填、格式、长度及校验触发时机 |
| 缓存 | 当前步骤写入路径、读取时机、覆盖和清理策略 |
| 确认展示 | 下一页从哪里读取,是否需要格式化 |
| 接口 | 具体请求、字段路径、string 类型及空值策略 |
同一个字段在 Journey、表单、缓存和接口中的名字可能不同。表格中的路径必须逐项从真实配置、代码和协议核对。
8.4 实现并闭合数据流#
先通过现有 Journey 能力配置输入和约束,生成对应可读 view 和本地 mock。若确认页已有支持该字段的展示能力,同步配置;能力不足时,再扩展相应组件并评估复用产品。
接着检查提交当前步骤时是否会把字段校验、转换并写入正确缓存。进入确认页后应读到相同值;返回编辑再次前进,应读到修改后的值。最后核对真实请求体,确认字段归属和类型与后端一致。
8.5 自测案例#
| 场景 | 预期 |
|---|---|
| 首次进入,无预填值 | 展示空字段,行为符合设计 |
| 留空并继续 | 阻止进入下一步,显示必填提示 |
| 输入无效格式并继续 | 显示格式提示,不发送无效的业务提交 |
| 输入合法邮箱 | 校验通过,下一页展示一致 |
| 从确认页返回修改 | 再次前进展示新值,最终请求使用新值 |
| 接口返回业务错误 | 用户能理解结果并按约定重试,不无反馈卡住 |
| 重新进入或切换产品 | 缓存行为符合该产品约定,不出现错误串用 |
| 其他复用产品 | 原有字段和交互不被本次公共改动影响 |
这个需求的完成证据包括:配置/代码差异、页面截图、字段请求核对结果、异常与返回路径结果,以及发布时需要同步的翻译和 Journey。
9. 验证与排障:证明需求已经实现#
自测按“构建与代码检查 → 目标页面交互 → 真实接口 → App 主流程 → 复用方回归”逐步完成。检查范围由需求决定,已有证据通过后不必重复扩大测试。
| 记录维度 | 至少写清 |
|---|---|
| 环境 | 市场、产品、入口、前后端环境/PFB、前端版本 |
| 设备 | 浏览器/模拟器/真机、系统与 App 版本 |
| 场景 | 正常、无效输入、接口异常、返回修改、重新进入、受影响产品 |
| 证据 | 预期与实际结果、截图、请求参数/响应;注明 mock 或真实接口 |
| 未完成项 | 阻塞原因、尚未验证的范围与下一步 |
9.1 先分清在哪一层失败#
先按第 3 章选择调试环境:浏览器用于快速定位 H5 问题,模拟器配合 Safari 检查 App 内 H5,真机优先用于完整主流程自测。涉及支付、OTP 或地址选择等 App 页面时,不能以浏览器验证代替 App 链路验收。
| 现象 | 首先检查 |
|---|---|
| 页面 404 | 当前 APP_NAME、市场入口、路径前缀、是否重启开发服务 |
| 页面白屏 | Console、JS 资源、初始化异常和主请求结果 |
| 修改没有生效 | 是否运行本地版本、代理规则、当前产品配置、缓存 |
| 请求未命中预期服务 | ENV、代理目标、PFB、迁移配置和实际请求 URL |
| HTTP 200 但页面报错 | 业务码、响应结构、必需数据与调用方处理 |
| 字段不出现 | Journey 数据、组件匹配、显隐依赖、当前步骤 |
| 输入正确但请求值错误 | field_name、缓存路径、类型转换和下游组装 |
| 返回后信息丢失 | 步骤离开时写回、返回时读取、缓存 key 和清理时机 |
| 浏览器正常、App 异常 | Bridge、WebView 返回行为、登录和真实运行环境 |
| 某一市场正常、其他市场异常 | 市场入口、条件编译、区域配置、翻译和组件依赖 |
先复现并确认请求、响应和状态,再决定改动层次。不要因为错误出现在页面上就直接修改组件。
9.2 Mock 与真实联调#
Mock 用于接口未完成时的并行开发,以及稳定复现空数据、异常和特定分支。响应需要遵守真实契约,并把作用范围限定到目标接口/产品。
验证记录应写清哪些结果来自 mock、哪些已经通过真实接口。Mock 成功只能证明页面在该响应下的行为;真实登录、网关、PFB、后端校验和 App 行为需要相应环境的证据。
9.3 代码检查与运行验收#
依赖安装完成后,可执行项目工具。以下代码检查命令中路径需要替换为本次真实改动文件:
npx tsc --noEmit
npx eslint <本次修改的TS或TSX文件>
npx prettier --check <本次修改的文件>
git diff --check执行 npm run dev,在菜单选择“构建”并明确选择目标环境、市场和 nonmotor,完成目标构建检查。多个市场共用的改动,按影响范围验证对应构建和页面。
命令失败时区分本次引入的问题、已有问题和环境阻塞,保留准确结论。构建通过仍需浏览器验收。前端不默认要求新增单测文件,已有相关测试按需运行,业务路径以目标环境和页面验证为依据。
9.4 使用已有自动化用例#
优先查找 runbooks/ 中已有的页面用例,确认场景、市场、环境和预期与需求一致。执行时按 runbooks/index.json 的 executionOwner 选择对应 Skill,不混用两条执行链的 session 和结果。
新增交互应补充对应验收场景;自动化报告要能定位到步骤、截图、请求或其他证据。登录失败、配置缺失等阻塞不能被记录成业务通过。
10. 交付与发布:MR、提测、Casement 与回退#
本章接续第 5 章的迭代分支流程:本地自测完成 → 提交 MR → Review 与合入 → 按团队流程提测/发布 → Casement 部署 → 检查实际页面。代码、配置与接口是同一次交付的组成部分。
10.1 准备 MR 与 QA 交接资料#
MR 描述应包含业务问题、最终行为、影响页面/产品/市场、代码与配置改动,以及验证结果。涉及公共能力时列明调用方影响,涉及协议时说明字段变化。
提交前检查:有无无关文件、临时日志、账号或凭证;新增类型与真实数据是否一致;配置与 mock 是否按约定同步;自测是否覆盖用户回退和错误路径。
给 QA 的交接资料应包含完整入口、市场/产品、环境与版本、账号获取方式、需求范围、验收场景、自测结果及已知限制。验证记录格式见第 9 章。
10.2 前端交付物不只有代码#
| 物料 | 交付时核对 |
|---|---|
| 前端代码包 | 分支、版本、APP_NAME、市场、环境 |
| Journey | 目标产品、配置版本、组件兼容性、发布状态 |
| i18n / Transify | key、目标语言、插值和实际下发 |
| 图片 | 正式 CDN 地址、尺寸、加载效果 |
| PFC | 下发范围、字段结构、预期命中行为 |
| 后端接口 | 环境、版本、字段契约和发布依赖 |
| QA 验证资料 | 完整入口、场景、预期、自测证据与限制 |
物料范围按实际产品和市场确定,不照搬 Admin 后端所有物料全地区同步的要求。
10.3 在 Casement 部署迭代版本#
部署前先完成第 5.4 节的开发、自测、MR 合入与发布流程。然后在 Casement 中选择 nonmotor_h5 应用,进入对应 release-v1.x.xxx 迭代,部署该迭代对应的分支代码版本。

图为用户提供的 release-v1.3.318 Test 环境示例。使用时替换为当前迭代和目标环境,不直接沿用截图中的版本、PFB 或部署状态。
操作顺序:
- 在 My Application 中选择
nonmotor_h5,进入本次迭代的 release 页面。 - 确认当前环境,并检查本次需求需要的配置、Release Note 等发布物料。
- 在 Deployment → Service Deployment 中找到目标服务,使用 Deploy 进入部署操作,核对本次版本和目标环境后提交。
- 在部署记录中核对 Region、Env 和 Parameters (Git/PFB/ImageTag),确认版本、PFB 与本次联调或验证计划一致。
- 观察 Status,必要时通过 Detail 查看详情。
deploying表示仍在部署,不能视为完成;部署成功后再验证目标页面及业务链路。
MR 合入、版本发布、部署成功和业务验收分别是不同检查点。部署记录中的 Git/版本、PFB 和镜像信息应与预期对应,避免代码已合入但实际验证的仍是其他版本。
部署负责人、审批要求,以及发布版本/Tag 的具体生成操作仍需按团队约定补充。截图中的 Rollback 是平台入口,实际回滚前仍需检查代码与配置的兼容关系。
10.4 构建产物与市场范围#
deploy/nonmotor.json 定义了 nonmotor 部署模块。deploy/space_build.sh 读取部署环境中的 CID 作为 REGION,并设置 APP_NAME 进行构建;产物目录为 dist/nonmotor,部署使用 /nonmotor/ 页面路径,静态资源路径也包含环境和市场信息。
这意味着发布时要核对目标市场与应用,不能仅凭某一次构建完成就认定所有市场都已覆盖。Casement 的一条部署记录可以包含多个 Region,也可以只包含一个市场;以本次选择和部署结果为准,不要求开发者机械地逐市场点击部署。
10.5 发布顺序与回退#
发布前把代码、配置和接口依赖放在一起 Review。例如,Journey 引用了新组件时,需要确保目标代码包能够加载它;接口字段变化时,需要确认前后端版本组合的兼容性。
回退方案也要覆盖配置和接口配套关系。不能只回退前端包,却保留仅新包能处理的 Journey。
上线后检查目标入口、主流程、资源加载、业务错误和关键埋点。监控与验收范围应对应本次改动的市场、产品和场景。
11. 效率工具:日常查询、AI 协作与上手练习#
11.1 按问题选择工具#
| 要解决的问题 | 工具或入口 |
|---|---|
| 找代码和调用方 | IDE 全局搜索、rg、Git diff |
| 看页面请求与响应 | 浏览器 DevTools Network |
| 看样式、布局和运行错误 | Elements、Console、断点调试 |
| 核对视觉与交互设计 | Figma 及目标页面实际渲染 |
| 查询产品 Journey | Admin 产品工厂及仓库配置同步 Skill |
| 管理翻译 | Transify、Journey i18n 及项目读取链路 |
| 核对埋点 | TMS 定义与实际事件 |
| 排查线上表现 | IDAP 与必要的后端日志 |
| 执行回归 | 现有 Runbook 与对应执行 Skill |
具体平台 URL 和权限申请方式应从团队入口表获取,本文不把其他项目或旧环境的链接当作 nonmotor 当前入口。
11.2 给 AI 的输入要覆盖开发上下文#
可以使用下面的任务描述模板:
请在 nonmotor_h5 中实现以下需求。
市场、环境、构建环境:……
产品与完整页面入口:……
需求正文、设计来源:……
当前 Journey 来源:……
接口协议、字段与业务码:……
预期交互、错误和返回行为:……
影响范围与不应改动的部分:……
验收场景:……
先判断配置与代码的改动边界,列出影响文件和字段数据流,
按仓库 AGENTS.md 与本地 Skills 实现,提供验证结果和未解决项。仓库已有需求分析、TD、代码生成、Journey 查询/更新、mock、UI 验证、Runbook 和代码 Review 等 Skills。根据任务选择相应入口,编码前仍需应用完整工程规范。AI 不能替代开发者确认字段语义、配置范围和最终运行效果。
11.3 后端同学建议的上手顺序#
第一个需求可以选择已有组件支持的文案或字段配置调整,熟悉运行环境和交付流程;随后完成本指南中类似的字段数据流;再承接需要扩展组件的小型业务模块。
学习前端基础时,优先覆盖对象/数组、可选值、Promise、TypeScript 类型、React props/state、事件、Effect、Context/reducer 和基础布局。每个概念都回到当前页面找一个真实使用点。
12. 第一个需求的完成标准#
完成第一个需求时,逐项检查以下结果;“代码写完”只是其中一部分。
- 能说明目标产品的页面链路,并从 URL 定位到入口与业务代码。
- 明确了配置、代码和接口各自的改动范围。
- 用户输入、校验、缓存、确认展示和最终请求相互一致。
- 正常、异常、返回、重进以及受影响产品已按范围验证。
- 类型、lint/格式和目标构建的结果已记录,阻塞项说明准确。
- MR、QA 验证资料和配置/翻译/图片等物料齐全。
- 已明确发布依赖与回退方式,Review 后按团队流程交付。
13. 补充内容:后续专题#
前面的章节覆盖日常开发闭环。后续专题按“差异化开发 → 配置与上线控制 → 观测与排障”展开,每个专题配实际代码、平台操作和验证案例。以下保留为专题计划,尚未补齐的平台规则不作为已确认操作流程。
13.1 差异化开发#
| 专题 | 后续重点介绍 | 希望解决的问题 |
|---|---|---|
| 市场差异(条件编译) | REGION 与条件编译的关系;市场代码如何进入对应构建产物;条件编译与运行时判断的区别 |
同一份源码如何支持不同市场?修改某市场逻辑时,怎样判断其他市场是否受影响? |
| 产品差异 | 共享模板中的产品差异如何表达;Journey 配置、产品条件与专属组件的使用边界 | 相同页面中,不同产品为什么展示不同内容?新需求应该改配置还是扩展组件? |
13.2 配置与上线控制#
| 专题 | 后续重点介绍 | 希望解决的问题 |
|---|---|---|
| Transify 配置流程 | 文案 key 的申请/维护、多语言配置、项目接入、更新生效与页面验证流程 | 新增或修改文案需要经过哪些步骤?平台已修改但页面未更新时怎样排查? |
| 灰度功能 | 功能开关、灰度条件与命中判断;如何验证开启/关闭两条路径,以及逐步开放和回退 | 为什么同一个功能对不同用户表现不同?如何确认自己命中了灰度? |
| 产品工厂放量 | 产品工厂相关能力的放量入口、适用范围、命中规则、验证方式,以及扩大范围和回退流程 | 配置完成后如何逐步开放?怎样确认目标产品、市场与用户使用了预期版本? |
13.3 观测与排障#
| 专题 | 后续重点介绍 | 希望解决的问题 |
|---|---|---|
| TMS 埋点上报流程 | 埋点需求与事件定义、TMS 配置查询、页面/点击/曝光事件接入、参数映射,以及触发与上报验证 | 如何从埋点定义找到前端上报位置?怎样验证事件时机、参数及重复或漏报问题? |
| IDAP 日志查看与排查 | 查询入口与权限、市场/环境/时间范围筛选、接口与自定义日志查看,以及结合页面、产品和会话线索定位问题 | 页面报错或接口异常时从哪里查起?如何把前端日志、Network 请求与后端日志关联起来? |
这些专题会分别说明控制对象、配置入口、代码消费位置和验证方法,尤其区分功能灰度、市场构建、产品差异与产品工厂放量,避免把不同层面的控制机制混为一谈。
TMS 专题重点说明埋点定义、接入与上报验证;IDAP 专题重点说明运行日志和异常排查。后续会分别展示实际使用的查询入口,说明各平台能看到的数据及其边界。
本节先作为后续分享目录;具体平台操作、规则和示例将在对应专题中补充。
附录 A:团队操作信息待补充#
这些信息影响实际操作,在确认前不将示例或历史约定作为当前流程:
| 信息 | 当前状态 | 需要补齐的内容 |
|---|---|---|
| 分支与 Review | dev/release 命名和 MR 方向已确认 | Reviewer、审批要求、多人开发分支的远端协作约定 |
| 本地代理 | ZeroOmega、Whistle、证书和市场规则已整理 | 按目标环境实测;确认 TH/SG/PH 浏览器域名与 API 目标的对应关系 |
| iOS 模拟器 | Xcode、Simulator App 安装和系统代理步骤已整理 | 当前推荐的 App 构建、iOS runtime、Mac 架构兼容性及目标 App 业务入口 |
| 本地登录 | 待补充 | 测试账号获取、目标域名登录和登录态验证步骤 |
| PFB 联调 | 需按目标环境确认 | 设置方式、有效性检查、后端命中验证 |
| 部署与回滚 | Casement 应用、迭代入口及部署流程已确认 | 平台 URL、操作人、审批、版本/Tag 生成与具体回滚步骤 |
| 培训演示产品 | 待选定 | 市场、产品、完整入口、设计截图和演示数据 |
| 常用平台 | 能力已列出,链接待补齐 | Admin、Transify、TMS、IDAP、KMS 与权限申请入口 |
附录 B:依据与维护范围#
主要核对文件:.nvmrc、package.json、scripts/prompt.js、scripts/start.js、scripts/create-template.js、config/bizConfig.js、config/paths.js、config/webpack.config.js、config/nonmotor/my.json、deploy/nonmotor.json、deploy/space_build.sh、deploy/space_install.sh。
页面与数据流依据:src/pages/factoryV2/purchase5/index.tsx、App.tsx、src/pages/factory/model/queryProductFactoryJourney.ts、src/common/request.ts、src/common/nonmotor.ts、src/module/storage/helper.ts、src/InsEntry/validate/email.ts。
页面入口介绍补充核对:config/nonmotor/my.json、config/nonmotor/sg.json、config/common/my.json、config/ec/my.json、config/bizConfig/my.json、src/pages/factoryV2/pdp/index.tsx、src/pages/factoryV2/pdp/App.tsx、src/pages/factoryV2/model/queryProductFactoryJourney.ts;配置组装和输出规则核对 config/bizConfig.js、config/webpack.config.js 与 config/paths.js。common 应用的仓库维护约定来自团队提供的页面注册截图。
项目介绍补充核对(2026-10-10):Motor 流程基于 ins_h5 当前工作区的 config/bizConfig/{region}.json,以及 src/pages/id/motor/carPdp/components/GetQuoteBtn/index.tsx、quote/components/QuoteAddonPanel/index.tsx、quote/components/BottomBar/index.tsx、confirmPersonalInfo/components/ConfirmBtn/index.tsx;MY 的 carPdp/components/BottomBar、quoteList/App.tsx、common/components/QuoteCard、quoteDetail2/components/BottomBar;SG 的 carPdp/components/BottomBar、quoteList/components/QuoteCard、quoteDetail/components/BottomBar、quoteAddOn/components/BottomBar、applicationForm/App.tsx。上述 MY/SG 路径分别以 src/pages/my/、src/pages/sg/ 为前缀。
Nonmotor 复用机制基于 nonmotor_h5 当前工作区的七个 config/nonmotor/{region}.json、src/pages/factoryV2/hooks/useGenerateComponents.tsx、model/queryProductFactoryJourney.ts、pdp/syncComponents/index.ts、pdp/config/pdpConfig.tsx、purchase5/App.tsx、purchase5/config/index.ts、confirmInfo/App.tsx,以及 src/pages/factory/model/queryProductFactoryJourney.ts、src/pages/checkoutV2/App.tsx 和 model/{region}。Factory V2 的缩略路径均以 src/pages/factoryV2/ 为前缀。组织方式的业务原因结合团队本次说明整理;流程图是源码导航与配置的教学示意,未冒充所有市场产品的端到端实测结果。
开发规范依据:本仓库 AGENTS.md 及 .agents/skills/ 下的工程、Journey、Service、React、样式、MoneeDesign、运行时集成与埋点规范。后续维护应以当前源码和规范为准。
文档编排参考:admin后端开发流程,内容由用户提供的 HTML 读取。代理章节结合用户材料、ZeroOmega 安装页和随文引用的 Whistle 官方说明整理。本文未执行真实产品配置修改、业务操作或发布,也未代用户安装插件、根证书或切换代理。
分支及部署流程依据:用户确认的 dev-v1.x.xxx → release-v1.x.xxx → Casement 部署 流程,以及随文保存的 Casement 截图。截图仅用作操作位置说明,不作为当前部署结果或权限状态的证明。
模拟器流程依据:用户提供的模拟器安装截图,以及随文引用的 Apple 和 Whistle 官方说明;内部下载入口来自截图正文,版本与页面可用性未独立验证。
附录 C:市场代理规则#
以下按用户提供的域名整理,保留原有整站转发意图,目标统一为本地 HTTP 3000 服务;没有实际联网验证这些业务域名。每个市场/环境单独保存为规则组,按本次开发选择启用,不要把所有环境同时指向一套本地构建后混用。
# BR UAT
protection.uat.shopee.com.br http://localhost:3000
# TH Test
protection.test.shopee.co.th http://localhost:3000
# TH UAT
protection.uat.seainsurebroker.co.th http://localhost:3000
# SG Test
test.moneeinsureagency.sg http://localhost:3000
# SG UAT
uat.moneeinsureagency.sg http://localhost:3000
# MY Test
protection.test.shopee.com.my http://localhost:3000
# MY UAT
protection.uat.shopee.com.my http://localhost:3000
# VN Test
insurance.test.shopee.vn http://localhost:3000
# VN UAT
insurance.uat.shopee.vn http://localhost:3000
# ID Test
insurance.test.shopee.co.id http://localhost:3000
# ID UAT
insurance.uat.shopee.co.id http://localhost:3000
# PH Test
protection.test.moneeinsurebroker.com.ph http://localhost:3000
# PH UAT
protection.uat.moneeinsurebroker.com.ph http://localhost:3000整理时处理了以下重复与不一致:
- PH Test 原材料中的整组规则重复出现,合并为一组。
- 已有整站转发时,保留路径的子目录规则合并到整站规则,覆盖原有
/ins、/nonmotor、/common、/ec和/static等请求。 - PH UAT 原材料中
/ins/同时指向/ins和根路径,/common/也指向根路径。此处统一保留完整路径,与本地/应用名/页面.html的构建结构一致;不保留去掉应用前缀的目标。 - 目标显式补充
http://,源域名仍支持业务 HTTPS 请求经 Whistle 解密后转发到本地 HTTP 服务。
附录 D:Motor 市场流程与目录详解#
本附录供需要对照车险页面的同学深入阅读。第 1 章讲业务差异;这里保留 ID、MY、SG 的具体链路、团队目录截图,以及七个市场的入口示例。源码中存在历史与可选分支,表格不代表所有产品的固定步骤。
ID:车辆与报价逻辑分开,附加保障作为报价页分支#
当前 id/motor/ 的主链路可以沿以下页面阅读:
car-pdp.html → quote2.html → confirm-personal-info2.html → checkout.html
| 页面/分支 | 作用与代码位置 |
|---|---|
| 车险 PDP | id/motor/carPdp/;填写/选择车辆相关信息,GetQuoteBtn 成功后进入 quote2.html |
| 报价页 | id/motor/quote/;展示和调整报价、保障方案,BottomBar 进入个人信息确认 |
| 车辆配件、附加保障 | QuoteAddonPanel 分别打开 add-car-accessories2.html、add-additional-coverage2.html;返回报价页后读取缓存、更新选项,相关处理会触发重新报价 |
| 个人信息确认 | id/motor/confirmPersonalInfo/;确认车主等资料,写入 createPolicyParams、calcPremiums 后进入 Checkout |
车辆品牌和地区选择也有独立入口,例如 car-information.html、region-code-selector.html。这些是用户操作触发的辅助页面,不是每次投保都要依次经过的主步骤。
MY:从车辆信息获取报价列表,再进入报价详情#
当前汽车报价路径可读作:
car-pdp.html / car-pdp2.html → quote-list.html → quote-detail2.html → checkout.html
PDP 的 my/carPdp/components/BottomBar 进行预检、请求报价卡片,并把车辆信息和报价结果写入缓存;my/quoteList/App.tsx 读取缓存并展示卡片;my/common/components/QuoteCard 进入报价详情;my/quoteDetail2/components/BottomBar 处理进入 Checkout 前的业务逻辑。
报价详情还可打开 vehicle-info.html 修改车辆信息。摩托车与部分历史路径存在分支,例如 motorcycle-quote-list.html、quote-detail.html,因此不能把汽车示例原样套到所有 MY Motor 产品。
SG:报价详情之后,按保障内容决定是否进入 Add-ons#
SG 的报价列表路径可读作:
car-pdp.html → quote-list.html → quote-detail.html → [quote-addon.html] → application-form.html → checkout.html
sg/quoteDetail/components/BottomBar 根据当前方案的可用附加保障计算 hasAddOns:有附加保障时进入 quote-addon.html,否则直接进入投保表单。PDP 还保留进入 quote.html 等路径,续保也有专属分支;上面的列表路径用于说明当前代码中的一种业务编排。
这类差异解释了为什么不能简单把某市场的 Motor 页面复制后只换翻译:页面拆分、字段、报价前提、附加保障、缓存结构与下一步条件都可能变化。
不同市场的入口目录#

团队提供的目录截图:src/pages/id/motor/ 集中放置 ID 的车险主流程页面;其他市场在各自目录维护。截图中同时能看到 factory、factoryV2 和 checkoutV2,分别对应产品工厂模板与收银台。
以下是当前 config/bizConfig/{region}.json 已登记的代表页面,不表示它们全部属于同一条顺序流程。
| 市场 | 主要源码目录(相对 src/pages/) |
已登记的页面示例 |
|---|---|---|
| MY | my/ |
carPdp、quoteList、quoteDetail2、vehicleInfo |
| ID | id/motor/,以及部分 id/ 辅助页 |
carPdp、quote、addAdditionalCoverage、confirmPersonalInfo;carInformation |
| SG | sg/ |
carPdp、quoteList、quoteDetail、quoteAddOn、applicationForm、driverInfo |
| TH | th/ |
carPdp、quoteList、coverageDetail、applicationForm、confirmInfo、carPhoto |
| PH | ph/ |
carPdp2、quoteList、coverageDetail、vehicleInformation2、reviewConfirm、kyc |
| VN | vn/ |
carPdp、carInformation、applicationForm、confirmInfo |
| BR | br/ |
carPdp、selectCoverageInsurer、quote、selectPlan、applicationForm |