我想知道我们是否应该在我们的仓库中跟踪node_modules或在检查代码时进行npm安装?
答案 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置于版本控制之下。到目前为止,几乎所有这样做所带来的好处都已经过时了。
已发布的软件包无法再从npm注册表中轻松撤消。因此,您不必担心项目以前依赖的松散的依赖关系。
在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小时,则需要与他们联系。 但是:
如果您与支持人员联系,他们将检查删除该版本的软件包是否会破坏其他安装。如果是这样,我们将不会将其删除。
所以发生这种情况的机会很小,但是有方案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)
我想提供一条中间路。
node_modules
添加到git中。package-lock.json
文件确定依赖项版本。在极少数情况下,您无法访问NPM(或您使用的其他注册表)或NPM中的特定程序包,则可以拥有node_modules的副本,并且可以继续工作直到恢复访问。
答案 7 :(得分:0)
还需要考虑的另一件事是:检入node_modules
会更难/无法使用dependencies
和devDependencies
之间的区别。
另一方面,可以说,通过测试完全相同的代码推动生产是令人放心的 - 所以包括devDependencies
。
答案 8 :(得分:0)