在Heroku上创建node.js应用程序时,我应该将node_modules检入git吗?

Jas*_*fin 362 git heroku gitignore node.js npm

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

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

这些指令不会告诉您创建.gitignore node_modules,因此暗示应该将node_modules签入git.当我在git中包含node_modules时,我的入门应用程序正确运行.

当我按照更高级的例子:

https://devcenter.heroku.com/articles/realtime-polyglot-app-node-ruby-mongodb-socketio https://github.com/mongolab/tractorpush-server(source )

它指示我将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
Run Code Online (Sandbox Code Playgroud)

运行"heroku ps"确认崩溃.好的,没问题,所以我回滚了更改,将node_module添加回git存储库并从.gitignore中删除它.但是,即使在还原后,我仍然在部署时收到相同的错误消息,但现在应用程序再次正常运行.运行"heroku ps"告诉我应用程序正在运行.

所以我的问题是这样做的正确方法是什么?是否包含node_modules?为什么我回滚时仍然会收到错误消息?我的猜测是Heroku方面的git存储库处于不良状态?

Kos*_*tia 394

第二次更新

常见问题解答不再可用.

来自以下文件shrinkwrap:

如果您希望锁定包中包含的特定字节,例如,为了能够重现部署或构建100%的信心,那么您应该检查您的依赖关系到源代码控制,或者寻求其他一些可以验证的机制内容而不是版本.

Shannon和Steven之前曾提到这一点,但我认为,它应该是公认答案的一部分.


更新

针对以下建议列出的来源已更新.他们不再建议node_modules提交文件夹.

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

对于您部署的软件包(例如网站和应用程序),您应该使用npm shrinkwrap来锁定完整的依赖关系树:

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


原帖

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

检查node_modules到您部署的内容,例如网站和应用程序.不要将node_modules检查为git,以用于要重用的库和模块.使用npm管理开发环境中的依赖项,但不能在部署脚本中管理依赖项.

对于一些很好的理由,请阅读迈克尔罗杰斯的帖子.


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

  • @Kostia我们的用例非常常见.我们是志愿者,使用我们自己的机器,而不是公司的机器.对于开源来说,这似乎是一种非常常见的情况. (16认同)
  • 这是不正确的 - 实际上这是非常糟糕的主意.如果您在Windows上进行开发,然后在Linux上进行部署,则需要在部署时重建node_modules.这意味着 - 混乱.很多修改过的文件,不知道该怎么做. (10认同)
  • 这是不可能的 - 我们的一些开发人员开发目标窗口,其他人针对Linux,但相同的代码库.最好的方法是不提交节点模块 - oops. (8认同)
  • @ user3690202听起来你有一个非常传统的案例,而不是常态,所以说"这不正确"可能是夸大其词.话虽如此,不确定你的具体用例是什么,但我想不出有任何理由同时使用windows和linux进行开发.坚持一个,并在您支持的所有平台上运行测试或QA. (7认同)
  • @Adam切向,您可以将正在编译的文件添加到`.gitignore`吗?这样,源代码是git,任何编译的组件都没有,类似于在grunt和gulp项目中如何调用`dist`或`output`文件夹. (4认同)
  • 斯宾塞,我明白你的观点,但这个答案只是反映了在npm常见问题解答中所写的内容.在源更改后不更新它本来是错误的. (3认同)
  • @user3690202 你的部署脚本只需要运行 `npm rebuild`。 (2认同)
  • @ user3690202 最好的方法是让您的所有开发环境都相同。使用流浪者(vagrantup.com)。 (2认同)
  • 从npm shrinkwrap页面:`如果你想锁定包中包含的特定字节,例如对于能够重现部署或构建有100%的信心,那么你应该检查你的依赖关系到源代码控制,或者寻求一些可以验证内容而不是版本的其他机制 (2认同)
  • @BenGeorge,因为某些软件包(例如phantomjs的npm版本)会根据您所使用的平台安装预编译的二进制文件。 (2认同)

Jon*_*han 159

我最大的担心是没有检查node_modulesgit是10年后,当你的生产应用程序仍然在使用时,npm可能不在.或者npm可能会被破坏; 或者维护者可能决定从他们的存储库中删除您依赖的库; 或者您使用的版本可能会被删除.

这可以通过像maven这样的repo管理器来缓解,因为您可以随时使用自己的本地Nexus或Artifactory来维护镜像,使用您使用的软件包.据我所知,npm不存在这样的系统.对于像Bower和Jamjs这样的客户端库管理器也是如此.

如果您已将文件提交到您自己的git仓库,那么您可以在需要时更新它们,并且您可以获得可重复构建的舒适性以及您的应用程序因某些第三方操作而不会中断的知识.

  • 今天有很多选择:Nexus(https://issues.sonatype.org/browse/NEXUS-5852),Artifactory(https://www.jfrog.com/jira/browse/RTFACT-5143),npm_lazy(https:/ /github.com/mixu/npm_lazy),npm-lazy-mirror(https://www.npmjs.org/package/npm-lazy-mirror)等. (10认同)
  • 来自npmjs的引用常见问题解答:"如果您对依赖于npm生态系统感到偏执,则应该运行私有的npm镜像或私有缓存." 我认为这指出了你所指的问题,对吧? (4认同)
  • 一个例子https://developers.slashdot.org/story/16/03/23/0652204/how-one-dev-broke-node-and-thousands-of-projects-in-11-lines-of- JavaScript的 (3认同)
  • 如果你不提交你的依赖项(即最好是在一个单独的存储库中),即使一个月后也是危险的.有一天早上,当我克隆了我的一个项目并发现一个软件包版本已从npm删除时,我发现了.我花了半天时间更改所有版本的级联依赖项,以使npm update工作并再次构建. (3认同)
  • Npm不会在一夜之间消失,因此,好处与提交历史记录的不清晰性和巨大的捆绑包数量并没有很好地匹配。如果某人正在构建他们认为在10年内仍将处于活动状态的应用程序,则可以合理地预期它将在此过程中获得大量维护。关于NPM中断的观点是一个更好的论点,尽管减轻风险的方法可能比承诺来源更好。 (2认同)

Rya*_*gle 66

您不应该包含 node_modules在您的.gitignore(或者应该包含 node_modules部署到Heroku 的源中).

如果node_modules:

  • 存在那么npm install将使用这些vendored库和将重建任何二进制依赖与npm rebuild.
  • 如果不存在npm install必须获取所有依赖项本身,这为slug编译步骤增加了时间.

有关这些确切的步骤,请参阅Node.js buildpack源代码

但是,原始错误看起来是npm和版本之间的不兼容node.根据本指南始终明确设置engines您的部分是一个好主意,以避免这些类型的情况:packages.json

{
  "name": "myapp",
  "version": "0.0.1",
  "engines": {
    "node": "0.8.x",
    "npm":  "1.1.x"
  }
}
Run Code Online (Sandbox Code Playgroud)

这将确保dev/prod奇偶校验并减少将来出现此类情况的可能性.


iba*_*ash 22

在这个评论之后我打算离开这个:在Heroku上创建node.js应用程序时,我应该在node_modules中检查git吗?

但stackoverflow格式化它很奇怪.如果您没有相同的计算机并且正在检入node_modules,请在本机扩展上执行.gitignore.我们的.gitignore看起来像:

# Ignore native extensions in the node_modules folder (things changed by npm rebuild)
node_modules/**/*.node
node_modules/**/*.o
node_modules/**/*.a
node_modules/**/*.mk
node_modules/**/*.gypi
node_modules/**/*.target
node_modules/**/.deps/
node_modules/**/build/Makefile
node_modules/**/**/build/Makefile
Run Code Online (Sandbox Code Playgroud)

首先检查所有内容,然后让另一个开发人员执行以下操作来测试:

rm -rf node_modules
git checkout -- node_modules
npm rebuild
git status
Run Code Online (Sandbox Code Playgroud)

确保没有更改文件.


use*_*170 10

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

另一方面,node_modules不应该在git上提交.除了他们的大尺寸,包括他们在内的承诺可能会分散注意力.

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

  • 谢谢你的评论。我相信在您的生产服务器中运行的 node_modules 应该从 npm 安装生成,而不是从开发人员提交的任何内容生成。开发人员的 node_modules 文件夹不一定与 package.json 内容匹配。 (2认同)

小智 8

我一直在使用提交node_modules文件夹和收缩包装.这两种解决方案都没有让我高兴.

简而言之:已提交的node_modules会为存储库添加太多噪音.
而shrinkwrap.json不易管理,并且无法保证一些收缩包装项目将在几年内建成.

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

所以我花了很长时间才在节点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并将结果推送到远程仓库.


Jas*_*fin 5

对我有用的是将一个npm版本显式添加到package.json(“ npm”:“ 1.1.x”),而不是将node_modules检入git。部署起来可能会比较慢(因为每次都会下载软件包),但是检入它们时我无法编译这些软件包。Heroku正在寻找仅存在于我本地机器上的文件。


Ben*_*ier 5

来自Git 中的“node_modules”

\n
\n

回顾一下。

\n
    \n
  • 仅签入您部署的应用程序的 node_modules,而不签入您维护的可重用\n包。
  • \n
  • 任何已编译的依赖项都应签入其\n源,而不是编译目标,并且应 $ npm重建\n非部署。
  • \n
\n
\n

我最喜欢的部分:

\n
\n

所有将 node_modules 添加到 gitignore 的人,删除它\n狗屎,今天,它\xe2\x80\x99 是我们\xe2\x80\x99 时代的神器,我们都非常乐意离开\n。全局模块的时代已经结束。

\n
\n

(原来的链接是这个,但现在已经死了。感谢@Flavio 指出它。)*

\n