
npm publish 命令会无条件忽略一组硬编码的文件和目录(如 .git、.DS_Store、npm-debug.log 等),无论 package.json 的 "files" 字段或 .npmignore/.gitignore 中是否显式声明,这些文件均不会被包含在发布的包中。
npm publish 命令会无条件忽略一组硬编码的文件和目录(如 `.git`、`.ds_store`、`npm-debug.log` 等),无论 `package.json` 的 `"files"` 字段或 `.npmignore`/`.gitignore` 中是否显式声明,这些文件均不会被包含在发布的包中。
在构建和发布 Node.js 包时,理解 npm publish 的默认排除逻辑至关重要——它并非仅依赖 .npmignore 或 package.json#files,而是在底层预置了一组强制忽略规则(hardcoded ignore patterns)。这些规则优先级最高,无法通过常规配置覆盖,除非使用 ! 显式反向声明(但对部分模式仍无效,后文说明)。
✅ npm publish 永远忽略的文件/目录列表(v8/v9+ 稳定版本)
根据 npm 官方开发者文档,以下路径模式在 npm publish 执行时自动排除,且不可绕过(即使写入 "files" 数组或添加 !./.git 也不会生效):
.*.swp ._* .DS_Store .git .gitignore .hg .npmignore .npmrc .lock-wscript .svn .wafpickle-* config.gypi CVS npm-debug.log
⚠️ 注意:src 目录本身不在该默认忽略列表中。你遇到的 src 被意外排除,极可能是由其他原因导致(例如:package.json 中 "files" 字段未包含 "src",且未设置 "files" 时 npm 默认仅包含白名单文件;或存在隐式 .npmignore 继承规则;或使用了旧版 npm 的遗留行为)。请务必检查 package.json 是否缺失 "files" 配置,或运行 npm pack --dry-run 验证实际打包内容。
? 如何验证哪些文件会被发布?
执行以下命令可预览即将发布的文件结构,无需真正上传:
npm pack --dry-run # 或生成 tarball 后解压检查 npm pack && tar -tzf your-package-1.0.0.tgz
此外,启用详细日志可辅助诊断:
npm publish --dry-run --loglevel verbose
? 关键注意事项
- ! 反向规则对默认忽略项无效:在 .npmignore 中写 !./.git 不会恢复 .git 目录——因为它是硬编码排除,! 仅作用于 .npmignore/.gitignore 的普通匹配规则。
- "files" 字段是白名单机制:若设置了 "files",则只有列表中明确声明的路径会被包含,其余全部排除(包括 src、lib、README.md 等常见目录/文件)。未设置 "files" 时,npm 采用启发式默认(如包含 package.json、README、LICENSE、CHANGELOG 及主入口相关文件),但不保证包含 src/。
- .gitignore 仅在无 .npmignore 时作为后备:npm 优先读取 .npmignore;若不存在,则回退至 .gitignore。但二者均无法覆盖上述硬编码忽略项。
✅ 最佳实践建议
-
显式声明 "files"(推荐):避免隐式行为,提高可预测性。
{ "files": ["dist", "lib", "index.js", "types", "README.md"] } - 避免依赖 src/ 自动包含:始终将构建产物(如 dist/ 或 lib/)纳入 "files",而非源码目录。
- 定期用 npm pack --dry-run 验证:将其加入 CI 流程,防止意外遗漏关键文件。
- 勿尝试“解除”硬忽略项:如需调试信息,改用 console.log() 或独立日志文件,而非保留 npm-debug.log。
掌握这些底层规则,能显著减少发布失败、功能缺失等“神秘消失”问题,让包管理更稳健、可维护。










