
npm publish 命令内置一组硬编码的忽略规则,会无条件排除特定名称的文件和目录(如 .git、.DS_Store、npm-debug.log 等),即使未在 .npmignore 或 package.json#files 中声明;本文完整列出这些模式,并说明如何安全覆盖及验证。
npm publish 命令内置一组硬编码的忽略规则,会无条件排除特定名称的文件和目录(如 `.git`、`.ds_store`、`npm-debug.log` 等),即使未在 `.npmignore` 或 `package.json#files` 中声明;本文完整列出这些模式,并说明如何安全覆盖及验证。
在使用 npm publish 发布包时,开发者常遇到“文件莫名消失”的问题——例如名为 src 的子目录未出现在最终发布的 tarball 中,但既未被 .npmignore 显式排除,也未在 package.json 的 "files" 字段中遗漏。这种现象往往源于 npm 内置的强制忽略规则(hardcoded ignore patterns):它们独立于用户配置,在打包前由 npm CLI 直接过滤,优先级高于 .gitignore 和 .npmignore。
✅ npm publish 永远忽略的文件/目录模式(截至 npm v9)
以下模式匹配的文件或目录始终被排除,无论其路径深浅(如 ./src/、./packages/core/src/ 均适用):
.*.swp ._* .DS_Store .git .gitignore .hg .npmignore .npmrc .lock-wscript .svn .wafpickle-* config.gypi CVS npm-debug.log
? 注意:src 本身不在该列表中。你遇到的 src 被忽略,极可能源于其他原因(如 package.json 中 "files" 字段未包含 "src",或存在隐式 .npmignore 规则)。npm 官方明确说明:src/ 是完全合法且默认可发布的目录名——它不匹配任何硬编码模式。
? 如何验证与调试实际发布内容?
在执行 npm publish 前,务必用 npm pack 预览生成的 tarball 内容:
# 生成并查看压缩包结构(不上传) npm pack --dry-run # 或解压后检查 npm pack && tar -tzf package-name-1.0.0.tgz
若发现关键文件缺失,按以下顺序排查:
- 检查 package.json 是否定义了 "files" 字段 —— 一旦声明,仅该字段指定的路径会被包含(白名单模式);
- 检查项目根目录是否存在 .npmignore;若无,则回退至 .gitignore(但硬编码规则仍优先生效);
- 运行 npm ls --depth=0 确认当前工作区无意外的 publishConfig 覆盖;
- 使用 npm config list 确认无全局 .npmrc 干预。
⚠️ 覆盖硬编码规则?不推荐,但有例外方式
npm 不提供禁用硬编码忽略的开关。唯一合法绕过方式是:在 .npmignore(或 .gitignore)中使用 ! 取反规则显式“恢复”——但仅对部分模式有效(如 !.DS_Store 在某些 npm 版本中生效,而 !.git 则永远失败,因 .git 是核心元数据,禁止发布属安全强制策略)。
✅ 推荐做法:
- 始终显式声明 "files" 字段,精确控制发布内容(例:"files": ["dist", "lib", "index.js", "README.md"]);
- 避免依赖隐式包含逻辑;
- 将构建产物(如 dist/)与源码(如 src/)分离,并确保 "files" 包含目标目录。
✅ 总结
| 类型 | 是否可覆盖 | 示例 | 建议 |
|---|---|---|---|
| 硬编码忽略(如 .git, npm-debug.log) | ❌ 永远不可覆盖 | .git/config | 无需尝试恢复,应从源头清理 |
| 用户配置忽略(.npmignore / "files") | ✅ 完全可控 | !dist/** | 用 "files" 白名单最可靠 |
| 模糊行为(如 src 消失) | ⚠️ 实为配置误用 | src/ 未列在 "files" 中 | 以 npm pack + tar -tzf 为准 |
遵循“显式优于隐式”原则,主动管理 package.json#files,即可彻底规避此类陷阱,保障发布结果可预测、可复现。










