node js

时间:2016-06-02 08:01:15

标签: node.js npm npm-install

我是节点js的新手。我正在尝试构建一个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个不同的包创建2个不同的文件。是用户创建并告诉NPM的东西吗?

2 个答案:

答案 0 :(得分:4)

<强> TL;博士

在Windows上,npm根据脚本文件的 shebang行中指定的shell /解释器创建包装批处理文件(*.cmd)。

您所看到的是 npm模拟 Windows Unix shebang机制,其中第一行是一个可执行的纯文本文件(脚本),如果以魔术字符#!开头,则告诉操作系统将脚本传递给执行的解释器/ shell(请参阅我的this answer以获取更多信息)。

由于Windows不支持shebang行,npm会创建一个包装器 *.cmd(批处理)文件,该文件显式调用“二进制”文件(指定的脚本文件)在bin的{​​{1}}键中,在脚本文件的shebang行中指定了任何可执行文件。

换句话说: package.json解析脚本的shebang行以确定要调用的shell /解释器,并相应地创建包装器批处理脚本。

如果我们在npm包中查看./bin/jade.js,我们会看到jade为shebang行,这就是#!/usr/bin/env node包装文件调用jade.cmd的原因。
这是典型案例:用JavaScript编写的脚本,必须由Node.js引擎执行

但是,也可以指定任何其他shell /解释器,但这样做只有在 Windows <上也可以使用给定的shell /解释器时才有意义/强>;对于node.exe,这是给定的,但是,正如node的内容所示,使用 Unix默认shell mocha-casper.cmd({包/bin/sh中的{1}}文件包含shebang行./bin/mocha-casperjs)。

mocha-casper.js的制造商选择通过重新实现#!/bin/sh的Unix shell脚本作为mocha-casperjs来推广自己的Windows集成(也是批处理文件) - 但是,由于cmd.exe没有意识到这一点,因此该批处理文件不会放在PATH(全局)/不能仅通过名称发现(在项目上下文中调用CLI时)。

更一般地说,脚本也适用于Windows,使用shebang行与绝对,POSIX风格的路径 没有意义 - EXCEPT 如果目标shell /解释器是通过mocha-casperjs.bat 间接调用指定的,它会向npm发出信号,表明它应该被查找在PATH中(再次,请参阅我的this answer了解更多信息) (此外,包装器批处理文件也在其自己的目录中查找可执行文件,但这很少有用,因为即使您明确将它们添加为/usr/bin/env也不会将它们复制到那里您npm的{​​{1}}密钥中的条目。)

顺便说一下:npm 的最新版本还为Unix环境创建无扩展包装脚本,特别是Cygwin和Windows上的Ubuntu上的Bash。

创建自己的软件包时,对于CLI(“二进制文件”) - 直接可执行的脚本,其作用类似于命令行实用程序 - 也是在Windows上运行的npm软件包的一部分,你必须:

  • 在脚本中添加一个shebang行 - 即使您只打算在Windows上运行它们。

  • 将shebang行定义为package.json ;通常 - 如果您的脚本是用JavaScript编写的,并且必须使用bin执行 - 请使用:
    npm

  • #!/usr/bin/env <interpreter-executable-filename-without-extension> 文件的node密钥中,定义脚本的密钥,不带扩展名,因为#!/usr/bin/env node在创建包装批处理文件时直接附加到键名称(在Unix上,按照原样为键创建符号链接);例如。: package.json

  • 警告:如果bin中的.cmd键指向的脚本具有扩展名"bin": { "foo": "./bin/fooj.js" },但没有shebang行< / em>,包装器脚本将直接调用bin文件 ,默认情况下会使用WSH执行它(具体来说,使用 JScript ,它的JavaScript引擎而不是Node.js,它不会按预期工作 - 请参阅this question您将看到的症状。

答案 1 :(得分:1)

您可以告诉npm使用您的软件包提供的可执行文件可以从./node_modules/.bin目录(在本地安装的情况下)或全局(在全局安装模块时)访问。您应该将bin字段放入package.json并指定脚本的相对路径。例如,jade package.json包含以下代码:

"bin": {
  "jade": "./bin/jade.js"
}

当安装jade包时,npm通过生成(如果需要的话)包装脚本(./bin/jade.js)来使这个脚本(jade.cmd)可访问,其内容依赖于当前的操作系统,shell和脚本的类型你希望能够访问。 Jade使用.js脚本,npm为您的操作系统生成jade.cmd,它将启动节点并将脚本名称作为参数传递。但是mocha-casperjs使用shell脚本,因此生成的mocha-casperjs.cmd的内容不同 - 它启动sh.exe而不是节点。

您可以在此处阅读bin package.json字段:https://docs.npmjs.com/files/package.json#bin