npm的package.json中的bin在Windows上无法使用

26

我正在尝试通过 package.json 的 bin 属性启动我的CLI工具。

我有以下内容:

...
"name": "mycli",
"bin": "./bin/mycli",
...

当我在包路径下打开cmd并输入:"mycli"时,它会显示命令未被识别。

我应该运行npm命令吗?还是使用scripts属性?我是否错误地尝试访问bin属性?

4个回答

28

尝试在bin属性中指定您的cli工具的名称,例如:

"bin": {
  "mycli": "./bin/mycli" // or "/bin/mycli.js" if it's a .js file
}

然后,在您的项目文件夹内运行npm link,创建到当前文件夹的全局符号链接。

不要忘记在package.json文件中,在bin属性之前添加"preferGlobal": "true"属性,以便提醒用户全局安装您的模块。


/bin/mycli./bin/mycli 不是一样的吗?在我看来它们长得一样... - Edwin Pratt

18
无论我尝试连接我的应用程序时,都会遇到问题,Windows生成的脚本将尝试使用默认的Windows可执行文件(我不知道那是什么)运行*.js文件。我不确定原因是什么,可能是因为它是JavaScript文件。然而,我将生成的脚本与安装的其他模块进行比较,并发现如果让package.json引用的bin文件表现得像要在*nix机器上执行一样,npm将自动尝试添加对node的调用。
例如:
如果我的package.json看起来像这样:

myapp/package.json

"name": "myapp",
"bin": {
    "myapp": "./bin/myapp"
}

我的引用的 bin 文件看起来像这样:

myapp/bin/myapp

#!/usr/bin/env node
require("../server.js");

通过在myapp目录中运行npm link命令(该目录的根目录应该有package.json文件),会出现在%APPDATA%\npm中出现的2个生成的可执行文件,如下所示:

myapp

#!/bin/sh
basedir=`dirname "$0"`

case `uname` in
    *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac

if [ -x "$basedir/node" ]; then
  "$basedir/node"  "$basedir/node_modules/myapp/bin/myapp" "$@"
  ret=$?
else 
  node  "$basedir/node_modules/myapp/bin/myapp" "$@"
  ret=$?
fi
exit $ret

我的应用程序.cmd

@IF EXIST "%~dp0\node.exe" (
  "%~dp0\node.exe"  "%~dp0\node_modules\myapp\bin\myapp" %*
) ELSE (
  node  "%~dp0\node_modules\myapp\bin\myapp" %*
)
请注意,我不需要明确创建上述2个文件,我只需要将要执行的文件作为package.json中的bin文件,npm会进行文件创建。

行结尾符

还有一件事需要注意,当使用这种方法时,一定要确保您的行结尾符是正确的。我注意到我的bin文件在*nix机器上安装时出现错误:因为存在不正确的行结尾,所以会报错“:没有那个文件或目录”。感谢在文本文件中查看行结尾符提供的如何打印可见行结尾符的示例。

例如,如果您运行cat -e PATH_TO_BIN并得到以下内容:

#!/usr/bin/env node^M$
^M$
require("../index.js");^M$

你使用的行尾符号有误。如果你收到类似下面这样的提示信息:

#!/usr/bin/env node$
$
require("../index.js");$

应该是正确的行尾。


2
"#!/usr/bin/env node" 解决了我的问题,即 bin js 脚本无法被 node 执行。谢谢。 - svimre

6
如果您放置
#!/usr/bin/env node

在你的脚本的第一行,npm将创建必要的包装器脚本。

1

罗德里戈·梅德罗斯的答案对我有用,但只有当我在.js文件中也有shebang行时。

我还遇到了另一个问题。我已经安装了位于c:\Program files\nodejs的node.js,这是我的shebang行:

#!c:/program files/nodejs/node

这个无法生效,因为空格的原因。以下是正确的方法:

#!c:/progra~1/nodejs/node

1
这会破坏非Windows支持。如果您改用#!/usr/bin/env node(如文档中推荐的那样),npm将检测到并在Windows上生成适当的命令,同时它也将继续在macOS和Linux上工作。 - Jason C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接