我正在开发一个需要从shell中运行的node包。我知道我必须全局安装该软件包,但运行
$> npm install -g ./my_module
没有得到我想要的结果,也就是运行不了
$> my_module
结果在
my_module: : command not found
我不是直接运行我的Node包的入口文件(index.js
),感觉好像漏了点什么,我做错了什么?
在正确设置package.json
配置后(主要使用{"bin": {...}}
),您无需将其发布到NPM注册表,然后再下载以查看其是否正常工作。
npm link
正是为这种情况而生。如官方文档所述:https://docs.npmjs.com/cli/link:
在包文件夹中运行
npm link
将在全局文件夹{prefix}/lib/node_modules/中创建一个符号链接,该符号链接指向执行npm link
命令的包。
假设您拥有此项目:
-- my_module
-- -- index.js
-- -- cli.js
-- -- package.json
而且您有这个 package.json
文件:
{
"name": "my_module",
"bin": {
"my_module": "cli.js"
},
}
运行:
cd my_module
那么:
npm link
现在npm将在您的计算机中全局安装您的包。它将检查package.json
文件中的bin
条目,并将my_module
链接到cli.js
文件。这将通过在全局npm目录中创建符号链接来实现到当前目录。
现在,如果您在命令行中运行:
my_module
如果你更改了cli.js
的内容,下次运行my_module
时会反映出来,同时它将指向cli.js
文件。如果你将my_module
重命名为my_module2
,请使用npm unlink
然后再次使用npm link
。
另外,npm可以使用完整的url作为包名,在下载和安装包时将使用该url而不是查找npm注册表。你可以从自己的私人Git主机安装软件包,例如:
npm install -g https://github.com/Me/my_module
npm link
选项对我的情况非常有效。 - ddsultannpm ls -g
命令,它甚至显示为+-- my_module@0.0.2 -> .\E:\work\my_module
,但是当我运行需要"my_module"的JS文件node my_script.js
时,仍然出现"Error: Cannot find module 'my_module'"的错误。这可能是什么原因呢?我找到了一篇帖子,发现模块的package.json中的"main"入口指向一个不存在的文件,但在这里并非如此;主文件存在且正确。 - iko79请尝试打包模块并进行安装。
npm pack
然后全局安装它
npm i -g my_module-0.0.1.tgz
请告诉我这是否有效
npm link
对于调试很有用。但一旦经过充分测试,我认为这种解决方案就是合适的。 - aemonge我最近也遇到了同样的问题。 我开发了一个CLI模块,以便能够从任何地方调用它,将其发布到NPM注册表并使用-g
选项安装它,但是当从命令行调用它时,我仍然会收到command not found
错误。 在package.json
文件中添加bin
属性是解决问题的关键。
根据NPM文档:
许多软件包具有一个或多个可执行文件,它们希望将其安装到PATH中。 npm使这相当容易(实际上,它使用此功能来安装“npm”可执行文件。)
要使用此功能,请在您的
package.json
中提供一个bin
字段,该字段是命令名称与本地文件名的映射。 在安装时,npm将该文件的符号链接到全局安装的prefix/bin
或本地安装的./node_modules/.bin/
。
这意味着你的package.json
文件应该像这样:
{
"name": "foo-cli",
"version": "1.0.0",
"description": "A CLI to do Foo-ish things.",
"bin": {
"foo": "./cli.js"
},
"main": "main.js",
...
}
如果您只希望指定一个单一命令,则属性可以是单个字符串;如果您希望指定多个命令,则可以是映射。现在,您应该能够从命令行的任何位置调用 foo
。
npm list -g
给出了全局安装模块所在的路径。 (查看) 尝试将您的包放在那里。 - laggingreflex