feat: group prototype journeys and simplify HTML preview
This commit is contained in:
@@ -3,51 +3,55 @@
|
||||
## 输入
|
||||
|
||||
```text
|
||||
node scripts/serve_file.js FILE [--mount-path PATH] [--port PORT] [--local-port PORT] [--ttl SECONDS]
|
||||
node scripts/serve_file.js FILE [--host IP] [--port PORT] [--ttl SECONDS]
|
||||
```
|
||||
|
||||
- `FILE`:必须是存在的普通文件,建议使用绝对路径。
|
||||
- `--mount-path`:以 `/` 开头的 URL 路径,不能包含 `?`、`#`、空段或 `..`;不提供时按父目录名生成。
|
||||
- `--port`:Tailscale 对外 HTTP 端口,默认 `80`。
|
||||
- `--local-port`:Node 监听的 localhost 端口,默认自动选择空闲端口。
|
||||
- `--ttl`:服务存活时间,单位为秒,默认 `3600`(1 小时);到期同时关闭 Node 服务和对应
|
||||
Tailscale Serve 路由。
|
||||
- FILE:存在的普通文件;解析为规范绝对路径,服务其父目录。
|
||||
- --host:默认 127.0.0.1;支持 IP 或 localhost(等价于 127.0.0.1)。0.0.0.0 表示所有 IPv4 接口。
|
||||
- --port:默认 0,自动选择空闲端口;显式端口范围为 1..65535。
|
||||
- --ttl:默认 3600 秒,允许 1..2147483;过期关闭该服务。
|
||||
|
||||
Node 服务 `FILE` 的父目录,而不是把文件复制到其它地方。这样 HTML 可以加载同目录的 CSS、
|
||||
图片和其它资源,但也意味着同目录其它文件会对 tailnet 可见。Node 只监听 `127.0.0.1`,
|
||||
Tailscale Serve 负责把指定路径代理到这个本地端口。
|
||||
旧的 --mount-path、--local-port、--tailscale-port 参数不再接受。--port 现在仅表示 Node
|
||||
静态服务的监听端口。脚本不读取或改写任何外部网络配置。
|
||||
|
||||
## 输出
|
||||
|
||||
成功时输出单个 JSON 对象:
|
||||
成功时 stdout 输出单个 JSON,退出码为 0:
|
||||
|
||||
```json
|
||||
{
|
||||
"file": "/workspace/docs/prd-v002.html",
|
||||
"directory": "/workspace/docs",
|
||||
"mountPath": "/preview/billing",
|
||||
"ip": "100.101.102.103",
|
||||
"port": 80,
|
||||
"localPort": 43721,
|
||||
"file": "/workspace/preview/index.html",
|
||||
"directory": "/workspace/preview",
|
||||
"host": "127.0.0.1",
|
||||
"port": 43721,
|
||||
"pid": 12345,
|
||||
"ttl": 3600,
|
||||
"expiresAt": "2026-10-11T13:00:00.000Z",
|
||||
"url": "http://100.101.102.103/preview/billing/prd-v002.html",
|
||||
"stopCommand": "kill 12345 2>/dev/null || true; tailscale serve --http=80 --set-path=/preview/billing off"
|
||||
"expiresAt": "2026-10-19T13:00:00.000Z",
|
||||
"url": "http://127.0.0.1:43721/index.html",
|
||||
"urls": ["http://127.0.0.1:43721/index.html"],
|
||||
"reused": false,
|
||||
"stopCommand": "kill -TERM 12345"
|
||||
}
|
||||
```
|
||||
|
||||
调用方应把 `ip` 字段和 `url` 一起展示给用户:`ip` 是访问这次预览时应使用的 Tailscale
|
||||
IPv4,`url` 是可直接打开的完整 HTTP 地址。不要把 `127.0.0.1` 当成远程访问地址,也不
|
||||
要求用户必须使用 Tailscale hostname。
|
||||
url 是该服务器的本地可访问入口。绑定所有接口时,urls 还列出系统网络接口的 IPv4 候选链接;
|
||||
脚本不判断访问者在哪个网络,也不保证远端可达。路径含空格和中文时 URL 自动编码。
|
||||
根路径 / 同样返回输入文件;HTML 的相对 CSS/JS/图片按原目录提供。
|
||||
|
||||
失败时输出到 stderr,退出码非 0;调用方不能把部分 stdout 当成有效 URL。
|
||||
失败时 stderr 输出单个 JSON,例如:
|
||||
|
||||
## 状态和冲突
|
||||
```json
|
||||
{ "code": "PORT_IN_USE", "message": "listen EADDRINUSE ..." }
|
||||
```
|
||||
|
||||
脚本先读取 `tailscale serve status --json`,确认当前 Tailscale Serve 可用,然后启动 Node 本地
|
||||
服务并追加指定 `--set-path` 路由。应为不同预览使用不同 mount path;脚本不会执行全量重置。
|
||||
错误码包括 ARGUMENT、FILE_INVALID、PORT_IN_USE、START_FAILED、START_TIMEOUT、
|
||||
VERIFY_FAILED、BUSY;退出码为 2。成功 JSON 不包含认证探测 token。
|
||||
|
||||
Serve 配置由 Tailscale 持久保存,但 Node 服务默认在 1 小时后自动关闭并清理对应路由。需要
|
||||
提前停止时使用输出的命令,不能使用 `tailscale serve reset`,因为 reset 会清除该节点的全部
|
||||
Serve 配置。
|
||||
## 重复调用和生命周期
|
||||
|
||||
脚本按规范化文件路径、host、请求端口和 ttl 建立服务标识。在系统临时目录内保存当前用户
|
||||
的进程记录,启动通过目录锁串行化。调用时会以服务标识和探测 token 验证原进程;仍可用则
|
||||
返回 reused: true,且不续期。否则重新启动并更新记录,不凭 PID 盲目停止进程。
|
||||
|
||||
服务在 ttl 到期或接到 SIGTERM/SIGINT 后停止。重复调用不意味着续期;要改变有效期可使用
|
||||
新的 --ttl 参数或先停止原服务。调用方保存一次成功结果,之后直接使用 URL。
|
||||
|
||||
Reference in New Issue
Block a user