维护者手册

常见修改场景

添加新的 CLI 选项

  1. src/cli.js:141-178arg 配置中添加新选项
  2. runCmd 函数中读取并传递给 ncc() API
  3. src/index.js:37-61 的函数签名中添加对应参数
  4. 在核心逻辑中实现功能
  5. test/cli.js 中添加测试用例
  6. 更新 readme.md 中的选项列表

添加新的 Loader

  1. src/loaders/ 中创建 Loader 文件
  2. src/index.js 的 Webpack module.rules 中注册
  3. scripts/build.js 中添加编译步骤(如需要编译)或直接复制
  4. 如果 Loader 需要编译:在 scripts/build.js 中添加 checkUnknownAssets 调用

修改模块解析行为

关键位置:

  • 自定义 resolve 插件:src/index.js:138-162
  • TsconfigPathsPlugin 注册:src/index.js:117-136
  • byDependency 配置:src/index.js:310-327

修改后处理管道

finalizeHandlersrc/index.js:463-635)中的步骤有严格的顺序依赖。如需修改:

  • Terser 压缩必须在其他文本替换之前
  • __webpack_require__ 重命名必须在 assetBuilds 之前
  • Shebang 恢复必须在重命名之后

支持新的输出格式

ESM/CJS 检测逻辑在三个位置:

  • src/index.js:40(API 默认值)
  • src/cli.js:257-258(CLI 检测)
  • src/utils/has-type-module.js(底层检测)

升级 Webpack 版本

Webpack 是硬编码在 devDependencies 中的。升级后需要:

  1. 检查 src/index.js 中的配置 API 是否有破坏性变更
  2. 确认 compiler.hooks API 兼容
  3. 运行完整测试套件
  4. 注意 experiments 配置可能有变化

安全修改点

以下位置的修改通常是安全的:

位置安全操作
test/integration/添加/删除集成测试文件
test/cli.js添加 CLI 测试用例
src/loaders/empty-loader.js修改过滤包列表
src/utils/ncc-cache-dir.js修改缓存路径逻辑
.github/workflows/修改 CI 配置
examples/修改示例代码

高风险区域

位置风险注意事项
src/index.js Webpack 配置影响所有编译行为
src/index.js finalizeHandler步骤顺序敏感
src/index.js resolve 插件影响模块解析和构建容错
scripts/build.js影响自举和发布
src/loaders/ts-loader.js影响 TypeScript 支持

调试技巧

查看 Webpack 编译详情

ncc build input.js -d --stats-out stats.json

-d 启用调试日志,--stats-out 输出 Webpack stats。

调试模块解析

在 resolve 插件中添加 console.logsrc/index.js:140-162),查看哪些模块被重定向到 @@notfound.js

调试资源重定位

@vercel/webpack-asset-relocator-loader 支持 debugLog 选项(通过 --debug 传入),会输出资源检测和重定位的详细信息。

验证自举

# 使用 src/ 编译自身,验证产物能工作
node src/cli.js build src/index.js -o /tmp/ncc-test
node /tmp/ncc-test/index.js --help

发布检查清单

  1. 确保所有测试通过
  2. PR 标题符合 Conventional Commits 格式
  3. 合并到 main 后 semantic-release 自动发布
  4. 验证发布的包内容:npm pack @vercel/ncc --dry-run

已知限制

  • 动态 require:完全动态的 require(variable) 无法在构建时分析
  • 原生模块.node 文件需要作为 asset 输出,不能内联
  • V8 缓存 + ESM:不兼容,ESM 模式下自动禁用
  • 嵌套层级__nccwpck_require__ 重命名最多支持 9 层
  • Watch + Runncc run 不支持 --watch
  • 单入口:不支持多入口构建(多入口需要多次调用 API)

依赖更新策略

  • Webpack:谨慎升级,需要全套测试验证
  • Terser:通常安全升级
  • ts-loader:可能需要验证与不同 TypeScript 版本的兼容性
  • @vercel/webpack-asset-relocator-loader:核心依赖,升级后需要重点测试资源检测
  • 测试用依赖(express、mongoose 等):可以相对自由升级,只要集成测试通过