Skip to content

feat: 提供独立原生 CLI(crates/cli),脱离 Node/WASM 直接解析 stack #13

Description

@MasonChow

背景

目前对外只有 node_sdk(Rust→WASM,ESM)。消费方即使只想「喂一段 minified stacktrace + sourcemap,吐原始位置」,也被迫拖 Node 18+ 运行时。核心解析逻辑其实全在纯 Rust 的 crates/source_map_parser 库里,只差一个命令行壳。

诉求

新增 crates/cli[[bin]] target),产出单文件原生可执行,无需 Node / node_modules。子命令对齐现有库 API:map(map_error_stack)、lookup(lookup_token)、unpack(unpack_all_sources)。

CLI 用法规格(-h

顶层 source-map-parser --help

source-map-parser <VERSION>
Parse and map minified JS stack traces back to original source via source maps.

USAGE:
    source-map-parser <COMMAND> [OPTIONS]

COMMANDS:
    map       映射整段 error stack -> 原始位置(批量)
    lookup    映射单个 line:column -> 原始 token
    unpack    从 .map 提取内嵌 sourcesContent
    help      打印某子命令的帮助

GLOBAL OPTIONS:
    -o, --output <FILE>   结果写入文件,默认 stdout
        --pretty          JSON 缩进输出(默认单行紧凑)
    -q, --quiet           不输出进度/统计到 stderr
    -h, --help            打印帮助
    -V, --version         打印版本

EXIT CODES:
    0  全部映射成功    2  部分失败(见 fail[])
    1  参数/IO 错误    3  无可解析 stack

source-map-parser map --help

映射整段 error stack。stack 从 --stack 文件或 stdin(-) 读入。

USAGE:
    source-map-parser map --stack <FILE|-> (--map <FILE> | --map-dir <DIR> | --map-url-template <TPL>) [OPTIONS]

SOURCEMAP 来源(三选一,互斥):
        --map <FILE>            单一 .map 文件(stack 全部来自同一 bundle 时)
        --map-dir <DIR>         .map 目录,按 stack 里 JS 文件 basename 匹配
        --map-url-template <TPL> 由 JS URL 推 .map URL 的模板,含占位符 {url}
                                 例: "{url}.map" -> https://x/app.js 取 https://x/app.js.map
                                 仅做字符串替换,不 eval(不接受任意脚本 rule)

OPTIONS:
        --stack <FILE|->        error stack 输入,- 表示 stdin(必填)
        --format <v8|auto>      堆栈格式,默认 auto(自动识别 V8/Firefox/Safari)
        --context <N>           每帧附带原始源码上下文行数,默认 0(不取)
        --no-fetch              禁止任何网络请求(--map-url-template 时改为报错而非下载)

OUTPUT (JSON):
    { "success": [{ "raw", "source", "line", "column", "name", "context"? }],
      "fail":    [{ "raw", "reason" }] }

EXAMPLES:
    # 本地单 map
    source-map-parser map --stack err.txt --map app.js.map --pretty
    # stdin + 目录匹配 + 取 3 行上下文
    cat err.txt | source-map-parser map --stack - --map-dir ./maps --context 3
    # 按模板远程拉 map
    source-map-parser map --stack - --map-url-template "{url}.map" < err.txt

source-map-parser lookup --help

映射单个位置。

USAGE:
    source-map-parser lookup --map <FILE> --line <L> --column <C> [--context <N>]

OUTPUT (JSON):
    { "source", "line", "column", "name", "context"? }

EXAMPLE:
    source-map-parser lookup --map app.js.map --line 1 --column 24680 --context 5

source-map-parser unpack --help

提取 .map 内嵌 sourcesContent。

USAGE:
    source-map-parser unpack --map <FILE> [--out-dir <DIR>] [--list]

OPTIONS:
        --list              只列出 sources 路径,不落盘
        --out-dir <DIR>     按原始路径结构还原源码到目录

收益

  • 值班告警诊断等脚本可直接调二进制,去掉 Node 依赖与 npm install
  • --map-url-template 用纯字符串替换取代现有 node 脚本里 new Function(rule) 的 RCE 写法,顺带消掉那个安全隐患。
  • 复用现有 release CI 三平台矩阵,额外发 source-map-parser-<platform> 原生二进制即可。

说明

v0.5.0 的 bin(--from npm|github 更新器)解决的是「装/更新包」,不解决「脱离 Node 解析」——本 issue 补的是后者。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions