通过package.json安装“全局”npm依赖项

89

我有一些“全局”依赖项(jshint,csslint,buster等),我希望在通过npm install安装我的软件包时,可以自动安装并通过命令行执行。这个可能吗?

目前,我正在手动执行以下操作:

  1. npm install -g <package_name>
  2. 在我的项目中: npm link <package_name>

更新: 刚刚发现npm的此功能请求。似乎应该使用package.json中的scripts配置?

再次更新: 或者,根据npm文档的说明,也许我应该使用.gyp文件?我感到困惑。

3个回答

61

无法在package.json中将依赖项指定为“全局”。这是经过设计的,正如你所引用的Isaac在此功能请求中所述:

是的,我们永远不会这样做。

但是,在本地安装软件包时,“二进制文件”仍然可以使用。它们将位于.../node_modules/.bin/中,并且您应该能够通过preinstall脚本将它们排队执行。

虽然,如果一系列命令相当冗长(如“jshint、csslint、buster等”),您可能需要考虑使用构建工具,例如grunt来执行各种任务:

{
    // ...,

    "scripts": {
        "preinstall": "grunt"
    }
}

感谢@Jonathan。我认为你是对的。我目前有一个名为“install”的grunt任务,用于构建modernizr、jquery等,并将随机文件复制到我的lib文件夹中。这意味着开发人员需要自己安装全局包,但无论如何,这都不应该是我的应用程序关心的问题。 - gxc
1
你的应用程序应该记录其依赖项,并且在我看来,确保它们以某种方式存在。 - EndangeredMassa
3
根据 https://www.npmjs.org/doc/misc/npm-scripts.html 的说法,使用安装脚本是一种反模式。 - Fdr
4
如果需要的话,你可以在 preinstall 脚本中添加 "npm install -g"。 - Eduardo Russo

35

我真的很喜欢这个模式:安装本地依赖项,然后使用一个Bash脚本将PATH设置为./node_modules/.bin

文件: env.sh

# Add your local node_modules bin to the path for this command
export PATH="./node_modules/.bin:$PATH"

# execute the rest of the command
exec "$@"

接下来,您可以在任何bash命令之前使用此脚本。如果您与Makefile或npm脚本配对使用:

文件:Makefile

lint :
    ./env.sh csslint my_styles

文件:package.json

"scripts": {
  "lint": "./env.sh csslint my_styles"
}

这些文件中的任务似乎引用了csslint的全局位置,但实际上它们使用的是您的node_modules bin中的版本。

这样做的真正好处是,这些依赖关系可以轻松地进行版本控制,就像您的其他节点模块一样。如果您坚持使用全局安装解决方案,则可能会覆盖用户系统中某个特定版本,而该版本对他们的其他项目是必需的。


1
你能详细说明为什么每次想要调用 ./node_modules/.bin/ 命令时都要使用脚本设置路径吗?在你的例子中,每次运行 lint,你都会将 ./node_modules/.bin 添加到你的路径中,即使它已经存在。为什么不在你的配置文件中只设置一次路径呢?如果命令不存在,Shell 将继续在 $PATH 的其余部分查找。 - nshew13
1
我希望任何人都能使用它。我可以在我的个人资料中设置它,这样它就可以为我工作,但是其他想要在此模块上工作的人也必须这样做。请注意,在package.json的“scripts”中不再需要“./env.sh”。 - EndangeredMassa
2
我仍然不明白为什么要设置“PATH”。如果所有的“./node_modules/.bin/”命令都通过“env.sh”路由,那么为什么还要调整“PATH”呢?难道“exec ./node_modules/.bin/$@”不足以满足需求吗? - nshew13
@N13,这不一样,因为你可能有一些本地的二进制文件和一些全局的二进制文件。因此,如果所有的二进制文件都是本地的,那么你的方法就足够了,但是PATH方法允许你首先找到本地的二进制文件。话虽如此,我同意使用“env.sh”脚本似乎是不必要的,只需将PATH导出添加到bash配置文件/ rc脚本中即可。 - Jon L.
1
这对于点文件存储库非常有帮助,您可以轻松定义您期望在系统上的所有全局模块并提交它。感谢分享这个想法! - Matt Smith

8
你应该尝试这个:https://github.com/lastboy/package-script 我一直在使用它来直接从package.json安装全局npm包,对于不精通技术的客户,它非常好用。
它甚至会检查包是否已经安装,如果没有则安装!

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