一个.npmignore引发的 60MB 泄露:用 Codex 排查你的发布包
Anthropic 因为漏写.npmignore,让 Bun 默认生成的 60MBcli.js.map随 npm 包一起发布,下载者可以还原出 1906 个核心源文件。这件事给所有做 npm 包发布的团队敲了警钟:source map 一旦进了 tarball,等于把源码目录结构、注释、甚至内部逻辑全部公开。本文从排障视角出发,用 TaoToken 提供的兼容通道驱动 Codex,扫描package.json、.npmignore和构建产物,核对cli.js.map是否被正确排除,并输出 tarball 里不应出现的 source map 清单。TaoToken 官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 可创建 Key,API 地址为 https://taotoken.net/api。
一、原问题与场景:source map 为什么会被打进发布包
npm 发布时,npm pack或npm publish会把当前目录下符合规则的文件打包成 tarball。默认情况下,npm 会遵循.gitignore和.npmignore的排除规则,但有一个关键细节:如果项目里存在.npmignore,npm 会忽略.gitignore,只按.npmignore来。很多团队在.gitignore里写了*.map,以为发布时也会被排除,结果.npmignore缺失或没写对应规则,构建产物里的.map文件就跟着进了包。
Anthropic 这次的情况更典型:Bun 作为构建工具,默认生成cli.js.map,体积达到 60MB。这个文件本身是调试用的“翻译字典”,能把压缩后的 JS 还原成可读的 TypeScript 源码。一旦发布到 npm,任何人npm install后都能在node_modules里找到它,用 source map 解析工具还原出 1906 个源文件。这不是黑客攻击,纯粹是发布配置漏了一行。
对于普通项目,风险同样存在。前端库、Node CLI 工具、SDK 包,只要构建产物里有.map,而.npmignore没排除,就会重演同样的剧本。排查的核心就三件事:package.json的files字段有没有限制发布范围、.npmignore有没有排除*.map、实际npm pack出来的 tarball 里到底有没有 source map。
二、TaoToken 前置:创建 Key 并配置 Codex
TaoToken 在这里的角色是提供 Key 和兼容通道,让 Codex 能通过统一入口调用模型能力来完成扫描和核对。你不需要改 Codex 的源码,只需要把 Base URL 指向 TaoToken 的 API 地址。
第一步,打开 https://taotoken.net/?utm_source=taotoken_aicg_blog_end ,注册后进入控制台创建 API Key。Key 的格式是YOUR_API_KEY,实际使用时替换成你自己的。
第二步,找到 Codex 的配置文件。Codex 通常读取config.toml,路径一般在~/.codex/config.toml或项目根目录下的.codex/config.toml。如果你用的是 Claude Code 风格的配置,则对应settings.json和ANTHROPIC_*环境变量。本文以 Codex 的config.toml为例。
第三步,把 Base URL 填成https://taotoken.net/api。注意两点:不要带/v1,也不要填官网地址https://taotoken.net。API 地址和官网地址是两个不同的入口,填错会导致请求 404 或返回 HTML 而不是 JSON。
三、可复制配置:Codex 的 config.toml 与 .npmignore 补丁
先看 Codex 的config.toml配置。把下面这段写入你的配置文件,model字段按你实际可用的模型 ID 填写:
# ~/.codex/config.toml model = "YOUR_MODEL_ID" base_url = "https://taotoken.net/api" api_key = "YOUR_API_KEY"如果你更习惯用环境变量,也可以这样:
export OPENAI_BASE_URL="https://taotoken.net/api" export OPENAI_API_KEY="YOUR_API_KEY"配置完成后,Codex 的请求会走 TaoToken 的兼容通道。接下来是排查任务本身。你需要让 Codex 做三件事:读取package.json的files字段、读取.npmignore内容、检查构建输出目录里有哪些.map文件。
一个典型的.npmignore补丁应该包含这些行:
# 排除所有 source map *.map **/*.map # 排除构建缓存和临时文件 .cache/ dist/**/*.map build/**/*.map # 排除测试和覆盖率产物 coverage/ .nyc_output/如果项目用files字段白名单发布,则应该在package.json里明确只包含必要目录:
{ "files": [ "dist/**/*.js", "dist/**/*.d.ts", "!dist/**/*.map" ] }注意files字段里的!排除规则,npm 对它的支持有版本差异,最稳妥的做法还是.npmignore和files双管齐下。
四、验证请求与成功结果:让 Codex 输出 tarball 里的 source map 清单
配置好之后,向 Codex 发起排查请求。你可以直接用自然语言描述任务,比如:
“扫描当前项目的package.json、.npmignore和构建产物目录,列出所有会被npm pack打包进去的.map文件,并给出.npmignore需要补充的具体行。”
Codex 会依次读取文件、执行npm pack --dry-run或解析files字段,然后输出一份清单。成功的输出应该类似这样:
检测到以下 source map 文件可能进入发布包: - dist/cli.js.map (60.2 MB) - dist/utils.js.map (1.3 MB) - dist/index.js.map (0.8 MB) 当前 .npmignore 缺失以下规则: *.map **/*.map 建议补充到 .npmignore: *.map **/*.map dist/**/*.map如果 Codex 输出的是“未检测到 source map 进入发布包”,说明你的.npmignore或files字段已经正确排除了。这时候可以进一步验证:运行npm pack生成 tarball,然后用tar -tzf your-package-0.0.1.tgz | grep '\.map$'检查。如果没有输出,说明排除生效。
TaoToken 的兼容通道在这里保证 Codex 能稳定读取文件并返回结构化结果。如果请求失败,先检查 Base URL 是否填成了https://taotoken.net/api,以及 Key 是否有效。
五、本篇常见错排查
错误一:Base URL 填了官网地址。把https://taotoken.net填进base_url,请求会返回 HTML 页面而不是 API 响应,Codex 会报解析错误。正确值是https://taotoken.net/api,不带/v1。
错误二:.npmignore存在但规则写错。比如写了/dist/*.map,但实际文件在dist/subdir/下,斜杠位置不对导致没匹配上。建议用**/*.map这种递归匹配。
错误三:只改了.gitignore没改.npmignore。前面说过,有.npmignore时 npm 不看.gitignore。如果两个文件同时存在且规则不一致,以.npmignore为准。
错误四:files字段白名单没排除 map。如果files里写了"dist",npm 会包含dist下所有文件,包括.map。需要显式加"!dist/**/*.map",或者改用.npmignore排除。
错误五:构建工具在postbuild阶段重新生成 map。有些项目在prepare或prepublishOnly脚本里重新构建,如果构建配置没关 source map,即使.npmignore写了排除,新生成的文件也可能在打包前一刻出现。检查tsconfig.json的sourceMap字段和构建脚本。
错误六:Codex 读取文件权限不足。如果项目在受限目录下,Codex 可能无法读取.npmignore。确保运行 Codex 的用户对项目目录有读权限。
六、语义一致的 CTA
排查完成后,如果你需要长期在编码和 Agent 场景里使用 Codex 做类似的发布包审计、配置核对,可以走 Coding Plan 通道,把 TaoToken 作为统一的模型入口。如果只是临时验证模型输出,用模型对话页面即可。需要管理 Key 或查看接入文档,分别对应 API Keys 和接入文档入口。
具体来说:排障和接入配置问题,去 API Keys 页面确认 Key 状态,再对照接入文档检查config.toml或settings.json的字段;验证模型是否能正常返回,用模型对话发一条测试请求;长期编码和 Agent 工作流,选 Coding Plan。Claude Code 用户注意settings.json里的ANTHROPIC_BASE_URL和ANTHROPIC_API_KEY要对应 TaoToken 的 API 地址和 Key,不要混用官网地址。
回到这次 Anthropic 的教训:一个.npmignore漏写,60MB 的cli.js.map就把 1906 个源文件送上了公网。你的项目不一定有 51 万行代码,但只要发布包里带了 source map,源码结构就是公开的。用 Codex 跑一遍扫描,确认 tarball 里没有.map,比事后补救便宜得多。