7.6 KiB
7.6 KiB
name, short_description, description, version, author, license, metadata
| name | short_description | description | version | author | license | metadata | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| genarrative-dev-stack-port-routing | 修改 Genarrative 本地 dev 启动端口、代理目标、端口冲突处理时使用。 | 在 Genarrative 中修改 npm run dev / npm run dev:rust / npm run dev:web 的本地启动端口、端口可用性探测、端口漂移、SpacetimeDB publish server、api-server 环境变量、Vite 代理目标和后台 admin-web 启动串联时使用。 | 1.0.0 | Hermes Agent | MIT |
|
Genarrative 本地 dev 启动端口与代理目标串联流程
用于维护 Genarrative 本地开发栈启动脚本,重点覆盖 npm run dev / npm run dev:rust / npm run dev:web 的端口检查、端口漂移和后续流程目标传递。
适用场景
- 修改
scripts/dev-rust-stack.sh、scripts/dev-web-rust.mjs、scripts/dev-stack-port-utils.mjs。 - 处理
3000、3101、3102、8082等端口被占用导致本地开发栈启动失败。 - 排查 Vite 代理仍指向旧 api-server 端口、前端打开了旧 dev server、后台代理错配。
- 调整 SpacetimeDB standalone、publish、Rust
api-server、主站 Vite、后台 Vite 的启动顺序。 - 修改本地联调文档或
.hermes/shared-memory/pitfalls.md中的 dev 启动口径。
当前端口职责
默认优先端口:
- 主站 Vite:
3000,对浏览器通常展示为http://127.0.0.1:<web-port>/。 - Rust
api-server:8082,健康检查为http://127.0.0.1:<api-port>/healthz。 - SpacetimeDB standalone:
3101,健康检查为http://127.0.0.1:<spacetime-port>/v1/ping。 - 后台 Vite:
3102,后台地址为http://127.0.0.1:<admin-web-port>/admin/。
端口不可用时,脚本会从优先端口开始向后寻找可用端口。后续流程必须以解析后的实际端口为准,不能继续使用默认端口。
实现入口
package.jsondev和dev:rust:执行node scripts/run-bash-script.mjs scripts/dev-rust-stack.sh。dev:web:执行node scripts/dev-web-rust.mjs。
scripts/dev-stack-port-utils.mjsisPortAvailable(...):探测端口是否可监听。findAvailablePort(...):从优先端口向后寻找可用端口,0表示申请临时端口。resolveDevStackPorts(...):一次性解析 SpacetimeDB、api-server、主站 Vite、后台 Vite 端口,并避免本次解析结果互相冲突。- CLI 模式:
node scripts/dev-stack-port-utils.mjs resolve-dev-stack spacetime:127.0.0.1:3101 api:127.0.0.1:8082 web:0.0.0.0:3000 adminWeb:127.0.0.1:3102。
scripts/dev-rust-stack.sh- 解析 CLI 参数后,先计算
API_TARGET_HOST与ADMIN_WEB_TARGET_HOST。 - 调用
resolve_dev_stack_ports覆盖SPACETIME_PORT、API_PORT、WEB_PORT、ADMIN_WEB_PORT。 - 再构造
SPACETIME_SERVER和RUST_SERVER_TARGET。
- 解析 CLI 参数后,先计算
scripts/dev-web-rust.mjs- 单独启动主站前端时,也先用
findAvailablePort检查WEB_PORT/ 默认3000。
- 单独启动主站前端时,也先用
必须保持的传递链路
npm run dev / npm run dev:rust 中端口解析后,必须同步到以下位置:
- SpacetimeDB 启动:
spacetime start --listen-addr "${SPACETIME_HOST}:${SPACETIME_PORT}"。 - SpacetimeDB 发布:
spacetime publish ... --server "${SPACETIME_SERVER}"。 - Rust api-server:
GENARRATIVE_API_HOST、GENARRATIVE_API_PORT、GENARRATIVE_SPACETIME_SERVER_URL、GENARRATIVE_SPACETIME_DATABASE。 - api-server 健康检查:
wait_for_api_server "${RUST_SERVER_TARGET}/healthz" ...。 - 主站 Vite:
RUST_SERVER_TARGET、GENARRATIVE_RUNTIME_SERVER_TARGET、ADMIN_WEB_TARGET、ADMIN_WEB_PORT、--port=${WEB_PORT}、--host=${WEB_HOST}。 - 后台 Vite:
ADMIN_API_TARGET、GENARRATIVE_API_TARGET、GENARRATIVE_API_PORT、--port=${ADMIN_WEB_PORT}。 - 控制台日志:
[dev:ports]和[dev:rust] web/admin web/rust api/spacetime必须显示最终实际地址。
如果只改了其中一段,通常会出现:浏览器打开的前端可用,但 /api/* 代理到旧端口;后台页面可用但后台 API 失败;SpacetimeDB 启动在新端口但 publish 仍发往旧端口。
修改流程
- 先读当前脚本和文档:
scripts/dev-stack-port-utils.mjsscripts/dev-rust-stack.shscripts/dev-web-rust.mjsdocs/technical/RUST_LOCAL_AND_REMOTE_DEPLOYMENT_SCRIPTS_2026-04-22.md.hermes/shared-memory/pitfalls.md
- 优先改公共端口工具,不要把端口探测逻辑复制到多个脚本。
- 对 Bash 脚本只做局部补丁,避免整文件重写导致中文注释或换行大面积变化。
- 修改
dev-rust-stack.sh时确认变量顺序:- 先有
REPO_ROOT。 - 再计算
API_TARGET_HOST/ADMIN_WEB_TARGET_HOST。 - 再调用端口解析工具。
- 再构造
SPACETIME_SERVER/RUST_SERVER_TARGET。
- 先有
- 修改
dev:web时不要自动改后端目标策略;dev:web只负责主站 Vite 端口可用性与已有后端目标选择。 - 同步更新技术文档和团队共享记忆。
测试与验证
最小验证:
bash -n scripts/dev-rust-stack.sh
npm run test -- scripts/dev-stack-port-utils.test.ts
npm run check:encoding
node scripts/dev-stack-port-utils.mjs resolve-dev-stack spacetime:127.0.0.1:0 api:127.0.0.1:0 web:0.0.0.0:0 adminWeb:127.0.0.1:0
端口冲突回归测试建议:
- 用测试或临时 Node server 占用某个优先端口。
- 调用
findAvailablePort,断言结果大于被占用端口。 - 调用
resolveDevStackPorts,断言四个结果互不相同。 - 如果实际启动完整栈,观察控制台:
[dev:ports] ... 不可用,改用 ...[dev:rust] rust api: http://...:<actual-api-port>[dev:rust] spacetime: http://...:<actual-spacetime-port>- 主站和后台 Vite 启动端口与日志一致。
完整启动属于长驻进程。需要 smoke 时用 background 方式启动,并另开命令检查 /healthz、/v1/ping 和页面端口;不要等待 npm run dev 自然退出。
常见坑
- 只让 Vite 自己漂移端口。 这样终端可能出现可访问前端,但脚本和文档仍认为是
3000,后台目标或日志会错。 - 只改 SpacetimeDB start,不改 publish。 standalone 可能监听新端口,但 publish 仍连旧
3101。 - 只改
GENARRATIVE_API_PORT,不改RUST_SERVER_TARGET。 api-server 已在新端口监听,但 Vite 代理仍打旧端口。 - 使用
0.0.0.0作为浏览器访问地址。 监听可以是0.0.0.0,展示给用户和健康检查通常用127.0.0.1。 - 端口探测和实际启动之间存在竞态。 已经探测可用的端口仍可能被外部进程抢占;SpacetimeDB 启动后仍要解析实际监听地址,api-server 和 Vite 失败时要打印清晰日志。
- 运行全仓库 lint 误判。 当前仓库可能有既有 lint 问题。验证本功能时优先运行定向测试、Bash 语法检查、编码检查,并在最终说明中区分既有 lint 失败与本次改动。
验收清单
- 端口工具有测试覆盖端口被占用和多端口互斥解析。
dev-rust-stack.sh通过bash -n。npm run dev/npm run dev:rust的 SpacetimeDB、publish、api-server、主站 Vite、后台 Vite 都使用实际端口。npm run dev:web在主站端口不可用时能切换到可用端口。- 文档同步更新
docs/technical/RUST_LOCAL_AND_REMOTE_DEPLOYMENT_SCRIPTS_2026-04-22.md。 - 长期踩坑同步更新
.hermes/shared-memory/pitfalls.md。 - 修改中文文件后运行
npm run check:encoding。