节点js中的node_modules / .bin / package.cmd文件
我是节点js的新手。 我正在尝试构build一个npm模块,并使用本地软件包名称在/node_modules/.bin文件夹中存在的cmd文件混淆了一下。
我安装了多个软件包作为依赖关系,发现cmd文件是不同的。
jade.cmd
@IF EXIST "%~dp0\node.exe" ( "%~dp0\node.exe" "%~dp0\..\jade\bin\jade" %* ) ELSE ( @SETLOCAL @SET PATHEXT=%PATHEXT:;.JS;=;% node "%~dp0\..\jade\bin\jade" %* )
摩卡casperjs.cmd
@IF EXIST "%~dp0\/bin/sh.exe" ( "%~dp0\/bin/sh.exe" "%~dp0\..\mocha-casperjs\bin\mocha-casperjs" %* ) ELSE ( @SETLOCAL @SET PATHEXT=%PATHEXT:;.JS;=;% /bin/sh "%~dp0\..\mocha-casperjs\bin\mocha-casperjs" %* )
我的问题是,如果它由NPM自动生成,为什么npm为2个不同的包创build2个不同的文件。 用户是否创build并告知NPM?
您可以告诉npm使您的程序包提供的可执行文件可从./node_modules/.bin
目录(在本地安装的情况下)或全局(在全局安装模块的情况下)访问。 您应该将bin
字段放入package.json
并指定脚本的相对path。 例如,jade package.json
包含以下代码:
"bin": { "jade": "./bin/jade.js" }
在安装jade软件包的时候,npm通过生成需要的包装脚本( jade.cmd
)来生成这个脚本( ./bin/jade.js
),这个脚本的内容取决于当前的操作系统,shell以及你想要创build的脚本的typesaccessble。 Jade使用.js
脚本,npm为您的操作系统生成jade.cmd
,它将启动节点并将脚本名称作为parameter passing。 但是mocha-casperjs使用shell脚本,所以生成的mocha-casperjs.cmd
是不同的 – 它启动sh.exe
而不是节点。
你可以在这里阅读关于package.json
bin
字段: https : //docs.npmjs.com/files/package.json#bin
TL;博士
在Windows上, npm
根据脚本文件的shebang行中指定的任何shell /解释器创build包装器batch file( *.cmd
)。
你看到的是npm模拟Windows的Unix shebang机制 ,其中可执行的纯文本文件(脚本)的第一行,如果它开始于魔法字符#!
,告诉操作系统什么解释器/壳传递脚本执行(见我的这个答案的更多信息)。
由于Windows不支持shebang行,因此npm
会创build一个wrapper *.cmd
(batch)文件,该文件显式调用“binary”文件(在package.json
的bin
键中指定的脚本文件)脚本文件的shebang行。
换句话说: npm
parsing脚本的shebang行以确定要调用的shell /解释器,并相应地创build包装器批处理脚本。
如果我们在jade
包中查看./bin/jade.js
,我们看到#!/usr/bin/env node
为shebang行,这就是jade.cmd
包装文件调用node.exe
。
这是典型的情况 : 用JavaScript编写的脚本必须由Node.js引擎执行 。
但是, 也可以指定任何其他shell /解释器 ,但是如果给定的shell /解释器在Windows上也可用,则这样做只有意义 。 对于node
,这是一个给定的,但是,正如mocha-casper.cmd
的内容所显示的那样,对于Unix默认shell /bin/sh
( mocha-casper.js
包中的./bin/mocha-casperjs
文件mocha-casper.js
包含shebang行#!/bin/sh
)。
mocha-casperjs
的制作者已经select通过重新实现 cmd.exe
的Unix shell脚本来实现自己的Windows集成,作为mocha-casperjs.bat
(也是一个batch file) – 然而,由于npm
并不知道这一点,所以batch file不放在PATH(全局)/不能被名称发现(当在项目上下文中调用CLI时)。
更一般地说, 对于在Windows上工作的脚本,使用具有绝对POSIX风格path的 shebang行是没有意义的 – 除非目标shell /解释器是通过/usr/bin/env
间接调用来指定的发信号给npm
,应该在PATH中查找(再次看到我的这个答案以获取更多信息)。
(另外,包装器batch file也在他们自己的目录中查找可执行文件,但这很less有帮助,因为即使你明确地将它们作为一个条目添加到你的package.json
的bin
key中, npm
也不会复制它们。)
npm
:最近的npm
版本也为Unix环境创build了无扩展的包装脚本,特别是Cygwin和Ubuntu上的Bash。
在创build自己的软件包时 ,对于CLI(“二进制文件”) – 作为命令行实用程序的直接可执行脚本 – 也是在Windows上工作的npm软件包的一部分,您必须:
-
添加一个shebang行到你的脚本 – 即使你只是打算在Windows上运行它们。
-
将shebang行定义为
#!/usr/bin/env <interpreter-executable-filename-without-extension>
; 通常情况下 – 如果您的脚本是用JavaScript编写的,并且必须使用node
执行 – 请使用:
#!/usr/bin/env node
-
在你的
package.json
文件的bin
键中, 定义没有扩展名的脚本键。 ,因为在创build包装器batch file时,.cmd
会直接附加到密钥名称上(在Unix上,为该密钥创build一个符号链接)。 例如:"bin": { "foo": "./bin/fooj.js" }
-
警告 :如果
package.json
的bin
键所指向的脚本具有扩展名.js
但没有任何指定的行 ,则包装脚本将直接调用.js
文件,默认情况下会使用WSH执行它(具体来说,使用JScript ,它的JavaScript引擎),而不是Node.js,它不会像预期的那样工作 – 看到这个问题 ,你会看到什么症状。