我正在尝试通过 package.json 的 bin
属性启动我的CLI工具。
我有以下内容:
...
"name": "mycli",
"bin": "./bin/mycli",
...
当我在包路径下打开cmd并输入:"mycli"时,它会显示命令未被识别。
我应该运行npm命令吗?还是使用scripts属性?我是否错误地尝试访问bin属性?
我正在尝试通过 package.json 的 bin
属性启动我的CLI工具。
我有以下内容:
...
"name": "mycli",
"bin": "./bin/mycli",
...
当我在包路径下打开cmd并输入:"mycli"时,它会显示命令未被识别。
我应该运行npm命令吗?还是使用scripts属性?我是否错误地尝试访问bin属性?
尝试在bin
属性中指定您的cli
工具的名称,例如:
"bin": {
"mycli": "./bin/mycli" // or "/bin/mycli.js" if it's a .js file
}
然后,在您的项目文件夹内运行npm link
,创建到当前文件夹的全局符号链接。
不要忘记在package.json
文件中,在bin
属性之前添加"preferGlobal": "true"
属性,以便提醒用户全局安装您的模块。
*.js
文件。我不确定原因是什么,可能是因为它是JavaScript文件。然而,我将生成的脚本与安装的其他模块进行比较,并发现如果让package.json
引用的bin
文件表现得像要在*nix
机器上执行一样,npm
将自动尝试添加对node的调用。package.json
看起来像这样:
"name": "myapp",
"bin": {
"myapp": "./bin/myapp"
}
我的引用的 bin 文件看起来像这样:
#!/usr/bin/env node
require("../server.js");
通过在myapp
目录中运行npm link
命令(该目录的根目录应该有package.json
文件),会出现在%APPDATA%\npm
中出现的2个生成的可执行文件,如下所示:
#!/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
@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");$
应该是正确的行尾。
#!/usr/bin/env node
罗德里戈·梅德罗斯的答案对我有用,但只有当我在.js文件中也有shebang行时。
我还遇到了另一个问题。我已经安装了位于c:\Program files\nodejs的node.js,这是我的shebang行:
#!c:/program files/nodejs/node
#!c:/progra~1/nodejs/node
#!/usr/bin/env node
(如文档中推荐的那样),npm将检测到并在Windows上生成适当的命令,同时它也将继续在macOS和Linux上工作。 - Jason C
/bin/mycli
和./bin/mycli
不是一样的吗?在我看来它们长得一样... - Edwin Pratt