如何解决全局npm模块依赖性问题

Node Package Manager (又名npm)使Web开发人员可以轻松访问许多很棒的JavaScript模块,并在尝试查找和管理应用程序依赖项时使我们的工作变得更加轻松。 这也使开发人员可以轻松地创建和发布自己的模块 ,这意味着其他开发人员可以通过简单的npm install -g your-tool来获取它们,并在需要时随时使用它们。 这是乌托邦! 对?

嗯,实际上...

我们有点问题

我永远不会说在安装npm模块时永远不要使用-g选项,但是我不得不说,过多使用它会导致问题。 我认为有两个原因可以减少对全局模块安装的使用,尤其是在构建,测试或整理工具(例如GulpKarmaJSHint等)的情况下。 在整篇文章中,我将主要提到Gulp,因为它很受欢迎并且说起来很有趣,但是,如果您不喜欢Gulp,只需在心理上将其替换为您喜欢的任何东西即可。

首先,即使您的项目依赖全局模块,也不会将全局模块列为您的项目中的依赖项,这会导致其他使用您的应用程序的步骤。 您知道需要使用Gulp才能使项目准备好投入生产,因此您可以在全球范围内安装和使用它。 当其他人想要开始工作或使用您的精彩开源项目时,他们不能只键入npm install并继续。 您最终不得不向README文件中添加说明,这些说明与

要使用此项目,请按照下列步骤操作

  • git clone仓库
  • 运行npm install
  • 运行npm install -g gulp
  • 运行gulp进行构建

我看到两个问题:首先,您添加了额外的全局安装Gulp的步骤,其次,您正在直接运行gulp 。 我看到可以避免的额外步骤(在全球范围内安装Gulp),而且我看到用户必须知道您的应用程序使用Gulp才能构建项目。 第一个问题是我在本文中要解决的主要问题,尽管第二个问题不那么重要,但是如果最终要切换工具,则需要更新说明。 我稍后讨论的解决方案应同时解决这两个问题。

与全局安装模块有关的第二个大问题是,由于安装了错误的模块版本,您可能会遇到冲突。 以下两个示例对此进行了说明:

  • 您六个月前创建了项目,当时使用的是最新版本的Gulp。 今天,有人克隆了您项目的存储库,并试图运行gulp进行构建,但遇到了错误。 这是因为克隆您的项目的人正在运行的Gulp的旧版本或新版本存在一些重大差异。
  • 您六个月前创建了一个使用Gulp的项目。 从那以后,您开始进行其他项目并在计算机上更新了Gulp。 现在,您回到这个旧项目并尝试运行gulp ,由于自从您上次触摸该项目以来已经更新了Gulp,因此您会遇到错误。 现在您被迫更新构建过程,以与新版本的Gulp配合使用,然后才能在项目上取得更多进展,而不是将其推迟到更方便的时间。

这些可能是非常严重的问题。 就像我之前说的,我不会发表笼统的声明,告诉您永远不要在全球范围内安装某些产品。 也有例外。

安全简要说明

默认情况下,在某些系统上,全局安装npm模块需要提升的特权。 如果发现自己正在运行sudo npm install -g a-package类的sudo npm install -g a-package ,则应更改此设置。 我们的npm初学者指南向您展示了如何。

规则例外

那么,您可以在全球范围内安装什么? 简而言之:您的项目不依赖的任何内容。 例如,我安装了一个名为local-web-server的全局模块。 每当我只有一些要在浏览器中查看的HTML文件时,我都会运行ws (这是local-web-server的命令),它将当前文件夹设置为localhost:8000的根目录,我可以在浏览器中打开下面的所有文档,然后对其进行测试。

我还遇到了以下情况:我想缩小不属于项目的JavaScript文件,或者至少不属于允许我建立正式构建过程的项目的一部分(出于愚蠢的“公司化”原因)。 为此,我安装了uglify-js ,可以在几秒钟内轻松地从命令行中缩小任何脚本。

解决方案

现在我们知道了问题可能出现的地方,我们如何预防这些问题? 您需要做的第一件事是在安装模块时删除-g 。 您应该将其替换为--save-dev以便将模块另存为开发依赖项,并且在有人运行npm install时将始终安装该模块。 那只能解决我提到的一个小问题,但这只是一个开始。

您需要知道的是,当在本地安装依赖项时,如果该依赖项具有要从命令行运行的任何脚本,则它们将放置在./node_modules/.bin/ 。 因此,现在,如果仅在本地安装Gulp,则可以在命令行中键入./node_modules/.bin/gulp来运行它。 当然,没有人想输入整个内容。您可以使用npm scripts修复此问题。

package.json文件中,您可以添加一个类似于以下内容的scripts属性:

{
    ...
    " scripts ": {
        " gulp ": "gulp"
     }
 }

现在,您可以在要运行本地版本的Gulp的任何时间运行npm run gulp gulp。 在检查您的PATH之前,npm脚本将在./node_modules/.bin/目录中寻找可执行命令的本地副本。 如果你愿意,你甚至可以通过添加传递其他参数咕嘟咕嘟--这些参数之前,如npm run gulp -- build-dev相当于gulp build-dev

令人遗憾的是,与全局使用Gulp相比,您仍然需要输入更多内容,但是有两种解决方法。 第一种方法(也可以解决我之前提到的一个问题)是使用npm脚本创建别名。 例如,您不必一定要将您的应用程序绑定到Gulp,因此您可以创建运行Gulp的脚本,但不要提及Gulp:

{
    ...
    " scripts ": {
        " build ": "gulp build-prod" ,
        " develop ": "gulp build-dev"
     }
 }

这样,您可以缩短对Gulp的调用,并使脚本保持通用。 通过使它们通用,您可以随时透明地删除Gulp并将其替换为其他内容,而无需其他人知道(除非他们在构建过程中进行工作,在这种情况下,他们应该已经知道它并且可能应该已经成为其中的一部分)离开Gulp的对话)。 (可选)甚至在有人运行npm install之后,您甚至可以在其中抛出postinstall脚本以自动运行构建过程。 这将清理您的自述文件。 此外,通过使用npm脚本,任何克隆您的项目的人都应该在package.json文件中获得有关您在项目上运行的所有进程的简单直接的文档。

除了使用npm脚本之外,还有另一个技巧可以使您使用命令行工具的本地安装:相对PATH 。 我在路径中添加了./node_modules/.bin/ ,以便只要我在项目的根目录中,只要输入命令名称即可访问命令工具。 我从对我写的另一篇文章评论中学到了这个技巧(感谢Gabriel Falkenberg )。

这些技巧并不一定能替代您想使用Gulp之类的每种情况,并且确实需要花一些工夫进行设置,但是我相信将最佳实践包括在依赖项中是最好的做法。 这将防止版本冲突(这首先是依赖关系管理器背后的主要原因之一),并将有助于简化某人选择项目所需的步骤。

超越

这可能有点过分,但是我也相信Node和npm是您项目的依赖项,它们有几个可能冲突的不同版本。 如果要确保您的应用程序适用于所有人,那么您需要某种方式来确保用户也安装了正确版本的Node和npm。

可以将Node和npm的本地副本安装到您​​的项目中! 但是,这并不能使所有事情都变得井井有条。 首先,每个操作系统上的Node都不相同,因此每个人仍然需要确保下载适用于其操作系统的操作系统。 其次,即使有安装通用节点的方法,您也需要确保每个人都有从命令行访问Node和npm的简单方法,例如确保每个人都将路径添加到本地副本Node和npm的PATH 。 没有简单的方法可以保证这一点。

因此,尽管我很希望能够在每个项目中强制执行特定版本的Node和npm,但我想不出一个好方法。 如果您认为这是一个好主意并提出了一个好的解决方案,请在评论中让我们都知道。 我希望看到一个足够简单的解决方案,使其可以成为标准做法!

最后的话

希望您现在能明白将您的工具列为项目的版本依赖项的重要性。 我也希望您愿意在自己的项目中完成实施这些实践所需的工作,以便我们可以将这些实践作为标准进行推进。 当然,除非您有一个更好的主意,在这种情况下,请大声说出来,让全世界了解它!

From: https://www.sitepoint.com/solve-global-npm-module-dependency-problem/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值