我应该检查文件夹"node_modules"在Heroku上创建Node.js应用程序时使用Git ?

我遵循了Heroku上Node.js的基本开始指令:

https://devcenter.heroku.com/categories/nodejs

这些指令并没有告诉你创建一个.gitignore node_modules,因此暗示文件夹node_modules应该签入Git。当我在Git存储库中包含node_modules时,我的入门应用程序正确运行。

当我遵循更高级的例子在:

它指示我将文件夹node_modules添加到文件.gitignore中。所以我从Git中删除了文件夹node_modules,将其添加到文件.gitignore中,然后重新部署。这次部署失败了,如下所示:

-----> Heroku receiving push
-----> Node.js app detected
-----> Resolving engine versions
Using Node.js version: 0.8.2
Using npm version: 1.0.106
-----> Fetching Node.js binaries
-----> Vendoring node into slug
-----> Installing dependencies with npm
Error: npm doesn't work with node v0.8.2
Required: node@0.4 || 0.5 || 0.6
at /tmp/node-npm-5iGk/bin/npm-cli.js:57:23
at Object.<anonymous> (/tmp/node-npm-5iGk/bin/npm-cli.js:77:3)
at Module._compile (module.js:449:26)
at Object.Module._extensions..js (module.js:467:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:362:17)
at require (module.js:378:17)
at Object.<anonymous> (/tmp/node-npm-5iGk/cli.js:2:1)
at Module._compile (module.js:449:26)
Error: npm doesn't work with node v0.8.2
Required: node@0.4 || 0.5 || 0.6
at /tmp/node-npm-5iGk/bin/npm-cli.js:57:23
at Object.<anonymous> (/tmp/node-npm-5iGk/bin/npm-cli.js:77:3)
at Module._compile (module.js:449:26)
at Object.Module._extensions..js (module.js:467:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:362:17)
at require (module.js:378:17)
at Object.<anonymous> (/tmp/node-npm-5iGk/cli.js:2:1)
at Module._compile (module.js:449:26)
Dependencies installed
-----> Discovering process types
Procfile declares types -> mongod, redis, web
-----> Compiled slug size is 5.0MB
-----> Launching... done, v9

跑步“heroku ps”;证实了坠机。好的,没有问题,所以我回滚了更改,将文件夹node_module添加回Git存储库,并从文件.gitignore中删除它。但是,即使在恢复之后,我仍然在部署时得到相同的错误消息,但现在应用程序再次正确运行了。跑步“heroku ps”;告诉我应用程序正在运行。

正确的做法是什么?是否包含文件夹node_modules ?为什么回滚时仍然会得到错误消息?我猜Heroku这边的Git仓库状态很差。

179096 次浏览

不要签入文件夹node_modules,而是为应用程序创建一个package.json文件。

包中。json文件指定应用程序的依赖项。Heroku可以告诉npm安装所有这些依赖项。你链接到的教程中包含了package.json文件的部分。

你应该在你的.gitignore文件中不包括文件夹node_modules(或者更确切地说应该包括文件夹node_modules在你的源代码中部署到Heroku)。

如果文件夹node_modules:

  • 存在npm install将使用这些提供的库,并将与npm rebuild重新构建任何二进制依赖项。
  • 不存在npm install将不得不自己获取所有依赖项,这将增加slug编译步骤的时间。

请参阅这些步骤的Node.js构建包源代码。

然而,最初的错误看起来是npm和Node.js版本之间的不兼容。总是根据本指南显式地设置你的packages.json文件的engines部分是一个好主意,以避免这些类型的情况:

{
"name": "myapp",
"version": "0.0.1",
"engines": {
"node": "0.8.x",
"npm":  "1.1.x"
}
}

这将确保开发/生产平价和减少这种情况在未来的可能性。

明确地将npm版本添加到文件package.json ("npm": "1.1.x")和检查文件夹node_modules到Git对我来说是有效的。

它的部署速度可能较慢(因为它每次都下载包),但当检入包时,我无法编译这些包。赫鲁库在找只存在于我本地盒子里的文件。

我对将文件夹node_modules检查到Git中最大的担忧是,10年后,当你的生产应用程序仍在使用时,npm可能不会出现。或者npm可能会被损坏;或者维护人员可能决定从他们的存储库中删除您所依赖的库;或者你使用的版本可能会被删减。

这可以通过像Maven这样的存储库管理器来缓解,因为你总是可以使用自己的本地联系 (Sonatype)或Artifactory来维护你所使用的包的镜像。据我所知,npm不存在这样的系统。客户端库管理器也一样,比如鲍尔Jam.js

如果您已经将文件提交到自己的Git存储库中,那么您可以在愿意的时候更新它们,并且您可以放心地进行可重复构建,并且您的应用程序不会因为某些第三方操作而崩溃。

第二次更新

常见问题解答不再可用。

来自shrinkwrap的文档:

如果您希望锁定包中包含的特定字节,例如有100%的信心能够重新生成部署或构建,那么您应该检查源代码控制中的依赖项,或者使用其他可以验证内容而不是版本的机制。

香农和史蒂文之前提到过这个问题,但我认为这应该是公认答案的一部分。


更新

下面列出的推荐已更新的来源。他们不再建议提交node_modules文件夹。

通常,没有。允许npm为你的包解析依赖关系。

对于你部署的包,比如网站和应用程序,你应该使用npm 收缩包装锁定您的完整依赖树:

https://docs.npmjs.com/cli/shrinkwrap


最初的发布

作为参考,npm FAQ清楚地回答了你的问题:

将你部署的东西(如网站)的node_modules检查到git中 和应用程序。不检查node_modules到git的库和模块 打算被重用。使用npm来管理开发中的依赖项

为了得到一些好的理由,请阅读Mikeal Rogers的帖子


来源:https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git

如果你正在为你的应用程序滚动你自己的模块,你可以:

这个用例非常棒。它让你可以很好地保留你专门为应用程序创建的模块,并且不会因为以后可以安装的依赖关系而变得混乱。

我一直在使用提交node_modules文件夹和收缩包装。两种解决方案都不能让我开心。

简而言之:已提交的node_modules文件夹给存储库添加了太多噪音。并且shrinkwrap.json不容易管理,并且不能保证在几年内会建立一些收缩包装的项目。

我发现Mozilla正在为他们的一个项目使用一个单独的存储库:https://github.com/mozilla-b2g/gaia-node-modules

因此,我没有花很长时间在Node.js CLI工具https://github.com/bestander/npm-git-lock中实现这个想法

在每次构建之前,添加:

npm-git-lock --repo [git@bitbucket.org:your/dedicated/node_modules/git/repository.git]

它将计算你的package.json文件的散列,并从远程存储库中检出文件夹node_modules的内容,或者,如果它是这个package.json文件的第一次构建,将执行一个清洁的npm install并将结果推到远程存储库。

我认为npm install不应该在生产环境中运行。有几件事可能会出错——npm宕机,下载更新的依赖项(收缩包装似乎已经解决了这个问题)是其中两件。

另一方面,文件夹node_modules不应该提交给Git。除了它们的大小之外,包含它们的提交可能会分散注意力。

最好的解决方案是:npm install应该在类似于生产环境的CI环境中运行。所有测试都将运行,并将创建一个包含所有依赖项的压缩发布文件。

我正在使用这个解决方案:

  1. 创建一个单独的存储库,保存文件夹node_modules。如果你有应该为特定平台构建的本地模块,那么为每个平台创建一个单独的存储库。

  2. 使用git submodule将这些存储库附加到你的项目存储库:

    git submodule add .../your_project_node_modules_windows.git node_modules_windows

    git submodule add .../your_project_node_modules_linux_x86_64 node_modules_linux_x86_64

  3. 创建一个从平台特定的node_modulesnode_modules目录的链接,并将node_modules添加到.gitignore

  4. < p > npm install运行。

  5. 提交子模块库更改。

  6. 提交项目存储库更改。

因此,你可以在不同平台上轻松地在node_modules之间切换(例如,如果你在OS X上开发并部署到Linux上)。

场景1:

一个场景:

你使用一个从npm中移除的包。如果所有模块都在node_modules文件夹中,那么这对您来说就不是问题。如果在包中只有包名。Json,你不能再得到它了。

如果一个包小于24小时,你可以很容易地从npm中删除它。 如果超过24小时,你需要联系他们。

但是:

如果您联系技术支持,他们将检查删除该版本的软件包是否会破坏任何其他安装。如果是,我们将不删除它。

read more

所以出现这种情况的几率很低,但有第二种情况……


场景2:

另一种情况是这样的:

你开发了一个企业版本的软件或者一个非常重要的软件,在你的package.json中写道:

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

使用该包的__abc0方法。

现在,studpid-package的开发人员将方法__abc0重命名为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(包。json仅)相比,数百MB(包。json,node_modules)…

可以做/应该考虑一下吗如果:

  • 软件是非常重要的。

  • 当某件事失败时,它会让你花钱。

  • 你不相信NPM注册表。NPM是中心化的,理论上可以被关闭。

不需要来发布node_modules文件夹在99.9%的情况下,如果:

  • 你只为自己开发一个软件。

  • 你已经编程了一些东西,只是想在GitHub上发布结果,因为其他人可能会对它感兴趣。


如果你不希望node_modules在你的存储库中,只需创建一个.gitignore文件并添加行node_modules