BF本地开发和调试使用指南
INFO
【前提条件】使用BFF本地开发,需要先升级到Rabetbase CLI 2.0:Rabetbase CLI - Vibe Coding研发套件
【快捷指引】通过help查看bff相关的指令集:rabetbase bff --help
【快捷指引】更新至最新版后创建BFF优先使用: rabetbase bff create (new 目前仍然兼容)
:::这篇文档面向要独立完成 BFF 开发的开发者,覆盖三条主路径:
- 把平台上的 BFF 拉到本地继续开发和维护
- 在本地创建 / 修改脚本后同步回平台
- 在 独立部署项目里对本地脚本做联调、日志排查和断点调试
Scheme
可以按这条主线走:
确认 appCode / 登录态 -> api pull -> list/detail -> pull 到本地 -> 修改文件 -> status -> push --dry-run -> push --yes -> runtime 本地调试先决条件
- 已登录 CLI
Scheme
rabetbase auth login- 当前项目能解析到正确的 `appcode`
Scheme
rabetbase doctor checkScheme
重点确认:
- `appCode`
- `env`
- `apiDir`
- `locale`- 当前项目是否已经拉过 `api.ts`
Scheme
rabetbase api pull
这一步很重要,因为:
- `HOOK` 脚本创建时会优先用 `api.ts` 里的 alias
- runtime 本地调试 HOOK 时,也会尝试从 `api.ts` 反查 alias- 业务工程根目录里已经有 `.rabetbase` 目录
第一次执行 `bff pull`、`bff create`、`bff push` 后一般都会出现这套本地结构。
- 本地目录约定
- BFF 本地文件统一放在业务工程根目录下的
Scheme
.rabetbase/bff/<appCode>/- 常见路径如下:
Scheme
| 类型 | 路径 |
|------|------|
| ENDPOINT | `.rabetbase/bff/<appCode>/ENDPOINT/<name>.js` |
| COMMON | `.rabetbase/bff/<appCode>/COMMON/<name>.js` |
| HOOK | `.rabetbase/bff/<appCode>/HOOK/<alias-or-datasetCode>/<operationType>/<functionNode>/<name>.js` |
额外还有两个常见文件/目录:
| 路径 | 作用 |
|------|------|
| `.rabetbase/bff.lock.json` | 记录本地与远端同步状态 |
| `.rabetbase/bff-trash/` | `bff delete` 实际执行后,本地文件移入的回收站目录 |
说明:
- `lock` 是 `pull / push / delete` 判断同步状态的核心依据
- 删除脚本时,本地文件不会直接硬删,而是移入 `bff-trash`
2.开发流程推荐
先看远端,再拉到本地
Scheme
这个路径适用于:
- 你要修改平台上已有的 BFF
- 你刚接手一个项目,需要先把远端脚本同步到本地
- 你怀疑本地版本落后于平台
### 1 查看远端脚本
```bash
rabetbase bff list --format json
rabetbase bff list --type COMMON --format json
rabetbase bff list --name getUserInfo --format json
```
如果你需要完整源码,继续查详情:
```bash
rabetbase bff detail --id <scriptid> --format json
```
建议做法:
1. 先 `list`
2. 找到目标 `id`
3. 再 `detail` 看当前远端代码和描述
### 2 先预览,再拉取
推荐先看 `dry-run`:
```bash
rabetbase bff pull --dry-run --format json
```
如果只想看某一类:
```bash
rabetbase bff pull --type ENDPOINT --dry-run --format json
```
预览里重点看:
- `lockKey`
- `filePath`
- `remoteId`
- `status`
常见状态:
- `would_pull`:会拉取并落到本地
- `conflict`:本地存在未同步改动,正式执行时会被保护
- `skipped`:当前脚本无法解析本地目标路径,或不满足拉取条件
### 3 正式拉取
```bash
rabetbase bff pull --format json
```
按类型拉:
```bash
rabetbase bff pull --type ENDPOINT --format json
```
如果你明确要让远端覆盖本地未同步改动,再用:
```bash
rabetbase bff pull --force --format json
```
注意:
- `--force` 会覆盖本地未同步内容
- 正常团队协作里,最好先确认当前目录下改动是否已备份或已提交
### 4 拉取后检查
```bash
rabetbase bff status --format json
```
如果你还想顺便发现“远端有、本地没有”的脚本:
```bash
rabetbase bff status --remote --format json
```本地新建 / 修改后同步回平台
Scheme
这个路径适用于:
- 新建一个 ENDPOINT / COMMON / HOOK
- 修改本地已有脚本并同步回平台
### 1 新建本地脚本
#### ENDPOINT
```bash
rabetbase bff create --type ENDPOINT --name getUserProfile --description "获取用户详情" --format json
```
#### COMMON
```bash
rabetbase bff create --type COMMON --name normalizePayload --description "公共参数归一化" --format json
```
#### HOOK
```bash
rabetbase bff create \
--type HOOK \
--name beforeGetList \
--alias appUser \
--operation-type getList \
--function-node before \
--description "列表前置处理" \
--format json
```
如果没有 alias,可退回 `--datasetcode`。
### 2 修改已有脚本
修改已有 BFF 时,不要只凭本地旧文件开改。推荐顺序是:
```bash
rabetbase bff list --format json
rabetbase bff detail --id <scriptid> --format json
rabetbase bff pull --type ENDPOINT --format json
```
然后再编辑本地 `.rabetbase/bff/...` 下的文件。
### 3 修改后先看状态
```bash
rabetbase bff status --format json
```
你至少要确认:
- 目标脚本已经被识别到
- `lockKey` 正常
- 没有你不想一起推上去的额外文件
### 4 推送前必须先预览
推荐最小范围推送:
```bash
rabetbase bff push --type ENDPOINT --name getUserProfile --dry-run --format json
```
全量预览:
```bash
rabetbase bff push --dry-run --format json
```
预览里重点看:
- `lockKey`
- `filePath`
- `remoteId`
- `mode`
- `status`
常见含义:
- `mode: create`:平台上还没有,推送后会新建
- `mode: update`:平台已有记录,推送后会更新
- `status: unchanged`:本地内容没变,不会真的推
- `status: would_push`:会执行推送
### 5 正式推送
`push` 是高风险写操作,正式执行时请带 `--yes`:
```bash
rabetbase bff push --yes --type ENDPOINT --name getUserProfile --format json
```
全量推送:
```bash
rabetbase bff push --yes --format json
```
只有在你明确知道自己在覆盖保护逻辑时,才用:
```bash
rabetbase bff push --force --yes --type ENDPOINT --name getUserProfile --format json
```
---删除脚本
Scheme
先预览:
```bash
rabetbase bff delete --target ENDPOINT/getUserProfile --dry-run --format json
```
或者用短名:
```bash
rabetbase bff delete --target getUserProfile --dry-run --format json
```
确认预览无误后再正式删:
```bash
rabetbase bff delete --yes --target ENDPOINT/getUserProfile --format json
```
删除时会发生的事:
- 远端脚本删除
- `bff.lock.json` 更新
- 本地文件移入 `.rabetbase/bff-trash/`
删除前建议至少做一次:
```bash
rabetbase bff list --name getUserProfile --format json
rabetbase bff status --format json
```3. 常见同步场景与建议动作
场景 A:我第一次接手项目,要把平台上的脚本拉下来
Scheme
### 场景 A:我第一次接手项目,要把平台上的脚本拉下来
```bash
rabetbase api pull
rabetbase bff list --format json
rabetbase bff pull --dry-run --format json
rabetbase bff pull --appcode <> --format json
rabetbase bff status --remote --format json
```场景 B:我新建了一个 ENDPOINT,想先本地调通再推平台
Scheme
### 场景 B:我新建了一个 ENDPOINT,想先本地调通再推平台
```bash
rabetbase bff create --type ENDPOINT --name demoOrder --format json
rabetbase bff status --format json
# 先去 runtime 本地调试,确认接口可用
rabetbase bff push --type ENDPOINT --name demoOrder --dry-run --format json
rabetbase bff push --yes --type ENDPOINT --name demoOrder --format json
```场景 C:平台已有脚本,我要基于最新版本修改
Scheme
### 场景 C:平台已有脚本,我要基于最新版本修改
```bash
rabetbase bff list --name demoOrder --format json
rabetbase bff detail --id <scriptid> --format json
rabetbase bff pull --type ENDPOINT --format json
# 修改本地文件
rabetbase bff status --format json
rabetbase bff push --type ENDPOINT --name demoOrder --dry-run --format json
rabetbase bff push --yes --type ENDPOINT --name demoOrder --format json
```场景 D:本地有改动,但远端也变了,不知道该 pull 还是 push
Scheme
### 场景 D:本地有改动,但远端也变了,不知道该 pull 还是 push
推荐顺序:
1. `bff detail` 看远端当前内容
2. `bff status --remote` 看本地与远端关系
3. 分支备份本地改动
4. 先 `pull --dry-run`
5. 再决定是否 `pull --force` 或手工合并
不要直接上来就 `push --force`。场景 E:我要删除一个脚本,但不确定 lockKey
Scheme
### 场景 E:我要删除一个脚本,但不确定 lockKey
```bash
rabetbase bff list --name demoOrder --format json
rabetbase bff status --format json
rabetbase bff delete --target demoOrder --dry-run --format json
```
如果出现重名,CLI 会要求你使用完整 `lockKey`。4.调试总览
Scheme
本地调试可以按下面这条主线执行:
确认 appCode -> 确认本地脚本文件 -> 打开 local-dev-mode ->启动 lovrabet-runtime -> 调接口 -> 看日志 -> Attach 9622 -> 打断点 -> 排错调试所需前置:
Rabetbase cli :脚本创建、修改、 部署等等。
本地部署项目 :用来调试脚本。
第一步:调试前确认基础条件
- 确认当前项目的 appCode 没有配错
Scheme
重点确认这几项:
- `appCode`
- `env`
- `apiDir`
> 注意:
> `appCode` 配错时,最容易出现“脚本明明存在但接口提示不存在”的误判。- 先拉一次 `api.ts`
Scheme
rabetbase api pull
这样做的原因:
- `HOOK` 本地调试时会依赖 alias 解析
- runtime 本地模式会尝试从 `api.ts` 反查 alias- 本地脚本目录约定如下:
| 类型 | 路径 |
|---|---|
| ENDPOINT | .rabetbase/bff/<appCode>/ENDPOINT/<name>.js |
| COMMON | .rabetbase/bff/<appCode>/COMMON/<name>.js |
| HOOK | .rabetbase/bff/<appCode>/HOOK/<alias-or-datasetCode>/<operationType>/<functionNode>/<name>.js |
注意:
runtime 本地模式命中的是这个目录下真实存在的文件 ,不是数据库存储的脚本文件。
第二步:打开本地脚本开发模式
- 打开本地脚本开发模式
Scheme
src/main/resources/application-dev.yml 文件下
lovrabet:
runtime:
script:
local-dev-mode: true
```- 启动成功后,控制台里建议确认出现下面这类日志:

- 点击编辑配置文件

- 点击+号

- 在IDE中新建Node.js/Chrome调试脚本

- 具体配置如下:

- 出现下面即为链接成功

- 您可以在这地方看到具体的调试信息

第三步:理解 runtime 怎么命中本地脚本
Scheme
打开 `local-dev-mode` 后,runtime 会优先从本地文件系统加载脚本,而不是从数据库加载。
脚本存放规则:
- ENDPOINT / COMMON:
.rabetbase/bff/<appcode>/<scripttype>/<scriptname>.js
- HOOK:
.rabetbase/bff/<appcode>/HOOK/<alias-or-datasetcode>/<operationtype>/<functionnode>/*.js
> 常见误区:
> - `appCode` 正确,但文件放错目录
> - `scriptName` 和文件名不一致
> - `HOOK` 的 `operationType` 或 `functionNode` 写错第四步:调试脚本
建议使用Apifox
调试endpoint脚本

Scheme
可直接调用的 HTTP 入口
runtime 当前有入口:
POST /api/endpoint/{appCode}/{scriptName}- 调试 COMMON
Scheme
COMMON 没有独立的公共 HTTP 调试入口。
推荐方式是:
1. 写一个 ENDPOINT 去调用 COMMON
2. 再调这个 ENDPOINT
示例调用方式:
return await context.client.bff.execute({
scriptName: 'normalizePayload',
params: { payload: params }
});
> 注意:
> COMMON 更适合通过 ENDPOINT 间接联调,不建议把它当成独立接口来理解。- 第七步:调试 HOOK
HOOK 不是独立 HTTP 入口,它必须靠真实数据操作触发。
调试时建议按这个顺序检查:
Scheme
本地 HOOK 文件路径是否正确
alias / datasetCode 是否正确
operationType 是否正确
functionNode 是否是你预期的 before 或 after
触发请求是否真的走到了目标数据库注意事项
- 首次进入调试可能会出现下图问题
解决办法:在提示之前手动调用一次endpoint脚本即可
原因:调试器监听端口不是应用启动时就打开的,而是在第一次真正执行“本地脚本”时,才懒加载创建出来。

- 本地脚本修改实时生效,不需要重启应用
- 场景 1:提示“脚本不存在”
Scheme
优先检查:
- `appCode` 是否正确
- `scriptName` 是否和文件名一致
- `local-dev-mode` 是否真的打开
- 文件路径是否符合 `.rabetbase/bff/<appCode>/...`- 场景 2:断点打不上
Scheme
优先检查:
- 是否在发请求前就完成了 Attach
- 是否真的连上了 `localhost:9622`
- 是否命中的是本地脚本模式
- 是否在正确的本地文件上打了断点