节点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模拟WindowsUnix shebang机制 ,其中可执行的纯文本文件(脚本)的第一行,如果它开始于魔法字符#! ,告诉操作系统什么解释器/壳传递脚本执行(见我的这个答案的更多信息)。

由于Windows不支持shebang行,因此npm会创build一个wrapper *.cmd (batch)文件,该文件显式调用“binary”文件(在package.jsonbin键中指定的脚本文件)脚本文件的shebang行。

换句话说: npmparsing脚本的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/shmocha-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.jsonbin 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.jsonbin键所指向的脚本具有扩展名.js没有任何指定的行 ,则包装脚本将直接调用.js文件,默认情况下会使用WSH执行它(具体来说,使用JScript ,它的JavaScript引擎),而不是Node.js,它不会像预期的那样工作 – 看到这个问题 ,你会看到什么症状。