我想知道我们是否应该在我们的 repo 中跟踪 node_modules 或者在检查代码时进行 npm install ?
9 回答
答案并不像Alberto Zaccagni 所说的那么简单。如果您开发应用程序(尤其是企业应用程序),在您的 git 存储库中包含 node_modules 是一个可行的选择,您选择哪种替代方案取决于您的项目。
因为他很好地反对 node_modules 我将专注于他们的论点。
想象一下,您刚刚完成了企业应用程序,您将需要支持它 3-5 年。你绝对不想依赖某人的 npm 模块,它明天就会消失,你不能再更新你的应用程序了。
或者您有无法从 Internet 访问的私有模块,并且您无法在 Internet 上构建您的应用程序。或者,也许您出于某种原因不想依赖最终构建在 npm 服务上。
您可以在 Addy Osmani 的这篇文章中找到优缺点(虽然是关于 Bower,但情况几乎相同)。最后,我将引用 Bower 主页和 Addy 的文章:
“如果您创作的软件包不打算供其他人使用(例如,您正在构建一个 Web 应用程序),则应始终将已安装的软件包检查到源代码管理中。”</p>
模块详细信息存储在 中packages.json
,这就足够了。无需签到node_modules
。
人们过去常常node_modules
在版本控制中存储以锁定模块的依赖关系,但现在不再需要使用npm shrinkwrap 。
正如@ChrisCM 在评论中所写,这一点的另一个理由:
同样值得注意的是,任何涉及本机扩展的模块都无法在架构间工作,需要重新构建。提供不将它们包括在回购中的具体理由。
我建议不要签入 node_modules,因为例如 PhantomJS 和 node-sass 等软件包会为当前系统安装适当的二进制文件。
这意味着如果一个开发npm install
人员在 Linux 上运行并签入 node_modules - 它不适用于另一个在 Windows 上克隆存储库的开发人员。
最好检查 npm install 下载并指向npm-shrinkwrap.json
它们的 tarball。您可以使用shrinkpack自动执行此过程。
这个话题很老了,我明白了。但是由于 npm 生态系统的情况发生了变化,我错过了对此处提供的参数的一些更新。
我总是建议不要将 node_modules 置于版本控制之下。到目前为止,在已接受答案的上下文中列出的几乎所有这样做的好处都已经过时了。
已发布的包不能再轻易地从 npm 注册表中撤销。因此,您不必担心失去项目之前所依赖的依赖项。
将 package-json.lock 文件放入 VCS 有助于频繁更新依赖项,尽管依赖于相同的 package.json 文件,但可能会导致不同的设置。
因此,在有离线构建工具的情况下将 node_modules 放入 VCS 可能被认为是唯一符合条件的用例。但是,node_modules 通常会增长得很快。任何更新都会改变很多文件。这正在以不同的方式影响存储库。如果您真的考虑长期影响,那也可能是一个障碍。
像 svn 这样的集中式 VCS 需要通过网络传输提交和签出的文件,这在签出或更新 node_modules 文件夹时会非常慢。
当涉及到 git 时,大量的附加文件会立即污染存储库。请记住,git 不会跟踪任何文件版本之间的差异,而是会在单个字符发生更改时立即存储文件的任一版本的副本。对任何依赖项的每次更新都会导致另一个大型变更集。由于这会影响备份和远程同步,您的 git 存储库将迅速变大。如果您决定稍后从 git 存储库中删除 node_modules,由于历史原因,它仍然是其中的一部分。如果您已将 git 存储库分发到某个远程服务器(例如用于备份),那么清理它是您将遇到的另一项痛苦且容易出错的任务。
因此,如果您关心高效的流程并希望保持“小”,我宁愿使用单独的工件存储库,例如 Nexos 存储库(或只是一些带有 ZIP 存档的 HTTP 服务器),提供一些以前获取的依赖项集以供下载。
不使用源代码控制进行跟踪node_modules
是正确的选择,因为一些 NodeJS 模块,如 MongoDB NodeJS 驱动程序,使用 NodeJS C++ 附加组件。这些附加组件是在运行npm install
命令时编译的。因此,当您跟踪node_modules
目录时,您可能会不小心提交特定于操作系统的二进制文件。
我同意ivoszz的观点,有时检查 node_modules 文件夹很有用,但是......
场景1:
一种情况:您使用从 npm 中删除的包。如果您在 node_modules 文件夹中拥有所有模块,那么这对您来说不是问题。如果你在 package.json 中只有包名,你就不能再得到它了。如果一个包的使用时间少于 24 小时,您可以轻松地将其从 npm 中删除。如果它超过 24 小时,那么您需要联系他们。但:
如果您联系支持人员,他们将检查删除该版本的软件包是否会破坏任何其他安装。如果是这样,我们不会删除它。
所以这种情况的可能性很低,但有第二种情况......
方案 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)推送到您的存储库,将占用您的内存空间。与数百 MB(package.json 和 node_modules)相比,只有几 kb(仅 package.json)……想想看。
如果出现以下情况,您可以这样做/应该考虑一下:
软件非常重要。
当某些事情失败时,它会花费你的钱。
你不信任 npm 注册表。npm 是集中式的,理论上可以关闭。
在 99.9% 的情况下,您不需要发布 node_modules 文件夹,如果:
您只为自己开发软件。
你已经编写了一些程序,只是想在 GitHub 上发布结果,因为其他人可能会对它感兴趣。
如果您不希望 node_modules 出现在您的存储库中,只需创建一个.gitignore
文件并添加行node_modules
.
我想提供一个中间的选择。
- 不要添加
node_modules
到 git 中。 - 使用
package-lock.json
文件来确定您的依赖版本。 - 在你的 CI 或发布过程中,当你发布一个版本时,复制 node_modules 文件夹并备份它(例如在云存储中)。
在极少数情况下,您无法访问 NPM(或您使用的其他注册表)或 NPM 中的特定包,您拥有 node_modules 的副本并且可以继续工作,直到您恢复访问权限。
要考虑的另一件事:签入node_modules
使使用和之间的差异变得更加困难/dependencies
不可能devDependencies
。
但另一方面,可以说将经过测试的完全相同的代码推送到生产环境是令人放心的——所以包括devDependencies
.
如果 package.json 中提到了依赖项,则不需要签入 node_modules。任何其他程序员都可以通过执行 npm install 来简单地获取它,并且 npm 足够聪明,可以在您的项目工作目录中创建 node_modules。