应该将“node_modules”文件夹包含在git存储库中

时间:2013-08-08 14:37:08

标签: git node.js version-control npm

我想知道我们是否应该在我们的仓库中跟踪node_modules或在检查代码时进行npm安装?

9 个答案:

答案 0 :(得分:151)

答案并不像Alberto Zaccagni所说的那么容易。如果您开发应用程序(尤其是企业应用程序),包括git repo中的node_modules是一个可行的选择,您选择哪个替代方案取决于您的项目。

因为他非常反对node_modules,所以我将专注于他们的论据。

想象一下,您刚刚完成了企业应用程序,您将需要支持它3 - 5年。你绝对不想依赖某个人的npm模块,这个模块明天就会消失,你再也无法更新你的应用了。

或者您的私人模块无法从互联网访问,您无法在互联网上构建您的应用程序。或者也许你不想因为某些原因依赖你在npm服务上的最终构建。

你可以找到利弊in this Addy Osmani article(尽管它与Bower有关,但情况几乎相同)。我将以Bower主页和Addy的文章引用结尾:

  

“如果您没有创作打算供他人使用的软件包   (例如,您正在构建一个Web应用程序),您应该始终检查已安装的软件包   进入源代码控制。“

答案 1 :(得分:93)

模块详细信息存储在packages.json中,这就足够了。无需签入node_modules

人们过去常常在版本控制中存储node_modules来锁定模块的依赖关系,但不再需要npm shrinkwrap

这一点的另一个理由,正如@ChrisCM在评论中所写:

  

另外值得注意的是,任何涉及本机扩展的模块都不适用于架构到架构,需要重建。提供具体理由,不将其包括在回购中。

答案 2 :(得分:17)

我建议不要检查node_modules ,因为像PhantomJS和node-sass这样的软件包会安装当前系统的相应二进制文件。

这意味着如果一个Dev在Linux上运行npm install并检入node_modules - 它将无法为另一个在Windows上克隆repo的Dev工作。

最好检查npm安装下载的tar包并向其指向npm-shrinkwrap.json。您可以使用shrinkpack自动完成此过程。

答案 3 :(得分:5)

不使用源代码控制跟踪node_modules是正确的选择,因为一些NodeJS模块(如MongoDB NodeJS驱动程序)使用NodeJS C ++附加组件。运行npm install命令时会编译这些加载项。因此,当您跟踪node_modules目录时,您可能会意外地提交特定于操作系统的二进制文件。

答案 4 :(得分:4)

我知道这个话题很老了。但是由于npm生态系统的情况发生变化,我缺少对此处提供的论点的一些更新。

我总是建议不要将node_modules置于版本控制之下。到目前为止,几乎所有这样做所带来的好处都已经过时了。

  1. 已发布的软件包无法再从npm注册表中轻松撤消。因此,您不必担心项目以前依赖的松散的依赖关系。

  2. 在VCS中放置package-json.lock文件有助于频繁更新依赖项,尽管依赖于相同的package.json文件,但可能导致不同的设置。

因此,在拥有离线构建工具的情况下,将node_modules放入VCS可能被认为是唯一剩下的合格用例。但是,node_modules通常会快速增长。任何更新都会更改很多文件。这以不同的方式影响存储库。如果您真的考虑到长期影响,那也可能是一个障碍。

像svn这样的集中式VCS要求通过网络传输已提交和已签出的文件,这在签出或更新node_modules文件夹时会非常缓慢。

当涉及git时,大量的其他文件将立即污染存储库。请记住,git不会跟踪任何文件版本之间的差异,而是会在单个字符更改后立即存储文件任一版本的副本。对任何依赖项的每次更新都会导致另一个较大的变更集。由于这会影响备份和远程同步,因此您的git存储库将迅速变得庞大。如果您决定稍后从git存储库中删除node_modules,则由于历史原因,它仍是其中的一部分。如果您已将git存储库分发到某个远程服务器(例如用于备份),则清理它是您将要执行的另一项痛苦且容易出错的任务。

因此,如果您关心高效的流程并且希望将事情保持在“较小”的水平,我宁愿使用单独的工件存储库,例如Nexos存储库(或仅一些带有ZIP归档文件的HTTP服务器),以提供一些以前获取的依赖项下载。

答案 5 :(得分:2)

我同意ivoszz的观点,有时有用的检查node_modules文件夹,但是 ...


场景1:

一种情况: 您使用的软件包已从npm中删除。 如果所有模块都位于node_modules文件夹中,那么这对您来说就不是问题。 如果在package.json中仅包含包名称,则无法再获取它。 如果包裹的使用时间少于24小时,则可以轻松地将其从npm中删除。 如果早于24小时,则需要与他们联系。 但是:

  

如果您与支持人员联系,他们将检查删除该版本的软件包是否会破坏其他安装。如果是这样,我们将不会将其删除。

read more

所以发生这种情况的机会很小,但是有方案2 ...


场景2:

是这种情况的另一种情况: 您开发企业版软件或非常重要的软件,然后将其写在package.json中:

"dependencies": {
    "studpid-package": "~1.0.1"
}

您使用该程序包的方法function1(x)

现在studpid-package的开发人员将方法function1(x)重命名为function2(x),他们犯了一个错误... 他们将其软件包的版本从1.0.1更改为1.1.0。 这是一个问题,因为下次调用npm install时,您将接受版本1.1.0,因为您使用了波浪号("studpid-package": "~1.0.1")。

现在致电function1(x)可能会导致错误和问题。


但是:

将整个node_modules文件夹(通常超过100 MB)推送到您的存储库中,将浪费您的内存空间。 相比之下,只有几kb(仅package.json)和数百MB(package.json和node_modules)……考虑一下。

可以做到/应该考虑,如果:

  • 该软件非常重要。

  • 出现故障时要花钱。

  • 您不信任npm注册表。 npm是集中式的,理论上可以关闭。

在以下情况下,您不需要在99.9%的情况下发布node_modules文件夹:

  • 您只是为自己开发软件。

  • 您已经编写了一些程序,只想在GitHub上发布结果,因为其他人可能对此感兴趣。


如果您不希望将node_modules放入存储库中,只需创建一个.gitignore文件并添加行node_modules

答案 6 :(得分:1)

我想提供一条中间路。

  1. 不要将node_modules添加到git中。
  2. 使用package-lock.json文件确定依赖项版本。
  3. 在CI或发布过程中,发布版本时,请复制node_modules文件夹并进行备份(例如,在云存储中)。

在极少数情况下,您无法访问NPM(或您使用的其他注册表)或NPM中的特定程序包,则可以拥有node_modules的副本,并且可以继续工作直到恢复访问。

答案 7 :(得分:0)

还需要考虑的另一件事是:检入node_modules会更难/无法使用dependenciesdevDependencies之间的区别。

另一方面,可以说,通过测试完全相同的代码推动生产是令人放心的 - 所以包括devDependencies

答案 8 :(得分:0)

如果package.json中提到了依赖项,则不需要签入node_modules。任何其他程序员都可以通过执行npm install来获得它,而npm非常聪明,可以在项目的工作目录中创建node_modules。