节点 js 中的 node_modules/.bin/package.cmd 文件 [英] node_modules/.bin/package.cmd file in node js

查看:157
本文介绍了节点 js 中的 node_modules/.bin/package.cmd 文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 node js 的新手.我正在尝试构建一个 npm 模块,并与/node_modules/.bin 文件夹中存在的 cmd 文件与本地包的名称有些混淆.

I am new to node js. I am trying to build a npm module and confused a bit with cmd file present in /node_modules/.bin folder with the name of the package locally.

我安装了多个包作为依赖,发现cmd文件不一样.

I installed multiple packages as dependencies and found that cmd files are different.

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" %*
)

mocha-casperjs.cmd

mocha-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 的东西吗?

My question is, if it is auto-generated by NPM, why npm creates 2 different files for 2 different packages. Is is something a user creates and tells NPM?

推荐答案

tl;dr

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

On Windows, npm creates the wrapper batch file (*.cmd) based on whatever shell/interpreter is specified in the script file's shebang line.

您看到的是 npm 对 Unix 的模拟 shebang 机制,如果它以魔术字符开头,则是可执行纯文本文件(脚本)的第一行 #!,告诉操作系统将脚本传递给哪个解释器/shell 来执行(有关更多信息,请参阅我的 这个答案信息).

What you're seeing is npm's emulation of the Unix shebang mechanism for Windows, where the very 1st line of an executable plain-text file (script), if it starts with magic characters #!, tells the OS what interpreter/shell to pass the script to for execution (see this answer of mine for more information).

由于 Windows 不支持 shebang 行,npm 创建了一个 wrapper *.cmd(批处理)文件,它显式调用"binary" 文件(在 package.jsonbin 键中指定的脚本文件)以及在脚本文件的 shebang 行中指定的任何可执行文件.

Since Windows doesn't support shebang lines, npm creates a wrapper *.cmd (batch) file, that explicitly invokes the "binary" file (the script file specified in the bin key of package.json) with whatever executable is specified in the script file's shebang line.

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

In other words: npm parses the script's shebang line to determine what shell/interpreter to invoke, and creates the wrapper batch script accordingly.

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

If we peek at ./bin/jade.js inside the jade package, we see #!/usr/bin/env node as the shebang line, which is why the jade.cmd wrapper file invokes node.exe.
This is the typical case: a script written in JavaScript that must be executed by the Node.js engine.

然而,也可以指定任何其他 shell/解释器,但这样做只有在给定的 shell/解释器也可用于 Windows;对于 node,这是给定的,但是,正如 mocha-casper.cmd 的内容所示,对于 Unix 默认 shell, /bin/sh (./bin/mocha-casperjs 包中的文件 mocha-casper.js 包含 shebang 行 #!/bin/sh).

However, any other shell/interpreter may be specified too, but doing so only makes sense if a given shell/interpreter is also available on Windows; for node, that is a given, but, as the contents of mocha-casper.cmd shows, it makes no sense with the Unix default shell, /bin/sh (the ./bin/mocha-casperjs file from package mocha-casper.js contains shebang line #!/bin/sh).

mocha-casperjs 的制造者选择通过重新实现cmd.exe 的 Unix shell 脚本来推出他们自己的 Windows 集成> 作为 mocha-casperjs.bat(也是一个批处理文件) - 然而,由于 npm 不知道这一点,这个批处理文件没有放在 PATH(全局)/无法仅通过名称发现(在项目上下文中调用 CLI 时).

The makers of the mocha-casperjs have chosen to roll their own Windows integration by re-implementing the Unix shell script for cmd.exe as mocha-casperjs.bat (also a batch file) - however, since npm is unaware of this, this batch file is not placed in the PATH (global) / not discoverable by name only (when calling CLIs in a project context).

更一般地,为了使脚本也能在 Windows 上运行,将shebang 行与绝对、POSIX 样式路径 一起使用是没有意义的 - EXCEPT 如果目标 shell/解释器是通过 /usr/bin/env间接调用指定的,这会向 发出信号npm 应该在 PATH 中查找它(再次,请参阅我的 this answer 以获取更多信息).
(此外,包装器批处理文件还会在其自己的 目录中查找可执行文件,但这很少有帮助,因为即使您明确指出 npm 也不会将它们复制到那里将它们添加为 package.jsonbin 键中的条目.)

More generally, for scripts to also work on Windows, it doesn't make sense to use shebang lines with absolute, POSIX-style paths - EXCEPT if the target shell/interpreter is specified by indirect invocation via /usr/bin/env, which signals to npm that it should be looked for in the PATH (again, see this answer of mine for more information).
(Additionally, the wrapper batch files also look in their own directory for the executable, but that is rarely helpful, given that npm wouldn't copy them there even if you explicitly added them as an entry in your package.json's bin key.)

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

As an aside: recent versions of npm also create extension-less wrapper scripts for Unix environments, notably Cygwin, and Bash on Ubuntu on Windows.

创建自己的包时,对于 CLI(二进制文件")——直接可执行的脚本,就像命令行实用程序——是 npm 包的一部分,也在 Windows 上工作,您必须:

When creating your own packages, for CLIs ("binaries") - directly executable scripts that act like command-line utilities - that are part of an npm package to work on Windows too, you must:

  • 向脚本添加shebang行 - 即使您只打算在 Windows 上运行它们.

  • Add a shebang line to your scripts - even if you only ever intend to run them on Windows.

将该shebang行定义为#!/usr/bin/env ;通常 - 如果您的脚本是用 JavaScript 编写的并且必须使用 node 执行 - 使用:
#!/usr/bin/env 节点

在您的 package.json 文件的 bin 键中,定义脚本的键不带扩展名.,因为 .cmd 在创建包装批处理文件时直接附加到键名(在 Unix 上,按原样为键创建了一个符号链接);例如.:"bin": { "foo": "./bin/fooj.js" }

In your package.json file's bin key, define the script's key without extension., because .cmd is directly appended to the key name when the wrapper batch file is created (on Unix, a symlink is created named for the key as-is); e.g.: "bin": { "foo": "./bin/fooj.js" }

警告:如果 package.json 中的 bin 键指向的脚本具有扩展名 .js没有shebang行,包装脚本将直接调用.js文件,默认情况下,它会用WSH(特别是使用其 JavaScript 引擎 JScript)而不是 Node.js,这不会按预期工作 - 请参阅这个问题了解您会看到的症状.

Caveat: If the script pointed to by the bin key in package.json has extension .js but has no shebang line, the wrapper script will invoke the .js file directly, which will by default execute it with WSH (specifically, with JScript, its JavaScript engine) rather than Node.js, which won't work as intended - see this question for what symptoms you would see.

这篇关于节点 js 中的 node_modules/.bin/package.cmd 文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆