Monorepo中使用npm link时如何忽略指定文件夹/文件?
.npmignore是否生效?
可以生效,但存在优先级规则,且不是最优方案。
具体解决方法
方案1:通过package.json的files字段控制(最推荐,出错概率最低)
npm在执行link、publish、install操作时,会优先读取包根目录package.json中的files字段,只有出现在该字段列表中的文件/目录才会被同步到依赖方的node_modules下,其余内容(包括nyc/这类缓存、测试目录)都会被自动忽略,配置方式如下:
在被依赖的A包根目录的package.json中添加配置,只保留需要对外暴露的产物目录:
// root/A/package.json { "name": "A", "version": "1.0.0", "main": "dist/index.js", "files": ["dist"] }
配置完成后重新执行npm link,B包的node_modules/A下就只会出现dist目录以及npm默认保留的package.json、README、LICENSE文件,不会再出现nyc目录。
注意:配置
files字段后,同目录下的.npmignore规则会完全失效,不需要重复配置。
方案2:使用.npmignore配置忽略规则
如果不想用files字段做白名单控制,也可以在A包根目录新建.npmignore文件,用黑名单模式排除不需要同步的目录:
# root/A/.npmignore nyc/ test/ coverage/ .nyc_output/ .git/ .eslintrc.js
配置后重新执行link操作,列表中的目录就不会被复制到依赖包的node_modules下。
方案3:monorepo场景原生workspaces方案(从根源避免问题)
手动执行npm link本身不适合monorepo的多包依赖场景,直接在仓库根目录的package.json中开启npm workspaces能力:
// root/package.json { "name": "monorepo-root", "private": true, "workspaces": ["A", "B"] }
配置后在根目录执行一次npm install,npm会自动将仓库内的包间依赖做软链关联,不需要手动执行link操作,且默认不会同步无关的缓存类目录到依赖引用中。
特殊场景说明
如果重新执行link后,你在B的node_modules/A下还是能看到nyc目录,先进入该目录执行ls -l(Windows下执行dir)检查A包是否为软链:如果是软链形式,说明你看到的nyc目录并不是被复制过去的,而是软链映射到A包原目录的内容,这种场景不需要删除原目录,只需要在B包的构建、测试、lint配置中,将node_modules/A/nyc加入排除规则即可,避免这类目录被工具误扫。
内容的提问来源于stack exchange,提问作者Surya Srivastava

