为何在包内执行npm install会忽略顶层package.json中的bin字段?
嘿,我懂你碰到的这个糟心事——你有个专门用来装CLI脚本的Node.js包,本来想从node_modules/.bin里运行它,结果npm install完全不理会顶层package.json里的bin字段,看了源码才发现是linkBins函数里的条件限制搞的鬼对吧?
先给你掰扯清楚这段逻辑:那段代码里的!gtop && path.basename(parent) !== "node_modules",意思是只有当包是全局安装(gtop为true),或者包本身就在node_modules目录下时,npm才会把包里的bin脚本链接到对应的.bin目录。而你的顶层package.json不在node_modules里,所以本地执行npm install时,自然就跳过了这一步。
下面给你几个实用的解决办法,按需选就行:
用
npm link手动建立链接:
进到你的CLI包目录里运行npm link,npm会把你的脚本链接到全局.bin目录,同时也会在本地项目的node_modules里创建软链,这样你就能直接在项目里调用这个CLI命令了。要是在其他项目里想用这个包,也可以在目标项目里跑npm link your-package-name。把包作为本地依赖安装:
别直接在顶层目录跑npm install,改用npm install ./path-to-your-cli-package(把路径换成你实际的包目录),这样npm会把你的包安装到项目的node_modules里,这时linkBins函数就会触发,自动把脚本链接到node_modules/.bin。在顶层package.json的scripts里加快捷命令:
要是不想折腾依赖结构,直接在顶层package.json的scripts字段里加一行:"scripts": { "your-cli-command": "./path-to-your-script.js" }之后运行
npm run your-cli-command就能执行你的脚本了,这种方式最简单,不用改任何依赖配置。(不推荐)修改npm源码:
虽然你可以改掉linkBins里的条件判断,但这是npm的内置逻辑,改完可能会影响其他包的正常安装,除非你有特殊需求,否则真不建议这么干。
内容的提问来源于stack exchange,提问作者zwol

