我遵循了Heroku上Node.js的基本入门说明:

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

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

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

用Node.js, Ruby, MongoDB和Socket构建实时,多语言应用程序。IO https://github.com/mongolab/tractorpush-server(源)

它指示我将文件夹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仓库状态很差。


当前回答

场景1:

一个场景:

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

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

But:

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

阅读更多

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


场景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")。

现在调用函数1(x)可能会导致错误和问题。


将整个node_modules文件夹(通常超过100 MB)推到存储库中会占用内存空间。 几个kb(包。json仅)相比,数百MB(包。Json & node_modules)…想想看。

你可以这样做/应该考虑如果:

软件非常重要。 当某件事失败了,你就得花钱。 你不相信NPM注册表。NPM是中心化的,理论上可以被关闭。

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

你为自己开发了一个软件。 你编程了一些东西,只是想在GitHub上发布结果,因为其他人可能会对它感兴趣。


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

其他回答

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

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

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

你不应该在你的.gitignore文件中包含node_modules文件夹(或者你应该在部署到Heroku的源代码中包含node_modules文件夹)。

如果文件夹node_modules:

存在时NPM安装将使用这些提供的库,并将通过NPM rebuild重建任何二进制依赖项。 如果不存在,那么NPM install将不得不自己获取所有依赖项,这将增加slug编译步骤的时间。

具体步骤请参阅Node.js构建包源代码。

然而,最初的错误看起来是npm和Node.js版本之间的不兼容。总是显式地设置包的引擎部分是个好主意。Json文件,以避免这些类型的情况:

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

这将确保开发/生产对等,并减少今后发生此类情况的可能性。

场景1:

一个场景:

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

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

But:

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

阅读更多

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


场景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")。

现在调用函数1(x)可能会导致错误和问题。


将整个node_modules文件夹(通常超过100 MB)推到存储库中会占用内存空间。 几个kb(包。json仅)相比,数百MB(包。Json & node_modules)…想想看。

你可以这样做/应该考虑如果:

软件非常重要。 当某件事失败了,你就得花钱。 你不相信NPM注册表。NPM是中心化的,理论上可以被关闭。

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

你为自己开发了一个软件。 你编程了一些东西,只是想在GitHub上发布结果,因为其他人可能会对它感兴趣。


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

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

简而言之:提交的node_modules文件夹给存储库添加了太多噪音。和收缩包装。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]

它将计算包的哈希值。Json文件,并将从远程存储库中检出文件夹node_modules内容,或者,如果它是这个包的第一个构建。Json文件,将做一个干净的NPM安装,并将结果推送到远程存储库。

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

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

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