繁体   English   中英

在 Heroku 上创建 Node.js 应用程序时,我应该将文件夹“node_modules”签入 Git 吗?

[英]Should I check in folder "node_modules" to Git when creating a Node.js app on Heroku?

我在这里遵循了 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 为什么我回滚时仍然会收到错误消息? 我的猜测是 Git 存储库在 Heroku 端处于错误状态。

第二次更新

FAQ 不再可用。

shrinkwrap的文档:

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

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


更新

为以下建议列出的来源已更新 他们不再建议node_modules文件夹。

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

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

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 检入 Git 的最大担心是 10 年后,当您的生产应用程序仍在使用时,npm 可能不存在了。 或者 npm 可能会损坏; 或者维护者可能决定从他们的存储库中删除您依赖的库; 或者您使用的版本可能会被删减。

这可以通过Maven等存储库管理器来缓解,因为您始终可以使用自己的本地Nexus (Sonatype) 或Artifactory来维护您使用的包的镜像。 据我了解,npm 不存在这样的系统。 BowerJam.js等客户端库管理器也是如此。

如果您已将文件提交到您自己的 Git 存储库,那么您可以随时更新它们,并且您可以舒适地进行可重复构建,并且知道您的应用程序不会因为某些第三方操作而中断。

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

如果文件夹node_modules

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

有关这些具体步骤,请参阅 Node.js buildpack 源代码。

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

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

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

发表评论后我打算离开这里: 在 Heroku 上创建 Node.js 应用程序时,我应该将文件夹“node_modules”签入 Git 吗?

但是 Stack Overflow 的格式很奇怪。

如果您没有相同的机器并且正在检查 node_modules,请在本机扩展上执行 a.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

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

rm -rf node_modules
git checkout -- node_modules
npm rebuild
git status

确保没有文件被更改。

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

另一方面,文件夹node_modules不应提交给 Git。 除了它们的大尺寸之外,包括它们在内的提交可能会让人分心。

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

我一直在使用提交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 版本添加到文件package.json ("npm": "1.1.x") 并且将文件夹node_modules 签入 Git 对我有用。

部署速度可能较慢(因为它每次都下载包),但我无法在签入包时编译这些包。Heroku 正在寻找只存在于我的本地机器上的文件。

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

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

来自Git 中的“node_modules”

回顾一下。

  • 仅为您部署的应用程序签入 node_modules,而不是您维护的可重用包。
  • 任何编译的依赖项都应该签入它们的源代码,而不是编译目标,并且应该在部署时 $ npm rebuild。

我最喜欢的部分:

所有将 node_modules 添加到你的 gitignore 的人,删除那个狗屎,今天,它是一个我们都乐于留下的时代的产物。 全局模块的时代已经结束。

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

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

  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. 运行npm install

  5. 提交子模块存储库更改。

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

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

场景 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

如果您正在滚动自己的特定于您的应用程序的模块,您可以:

  • 将那些(并且只有那些)保留在应用程序的/node_modules文件夹中,并将所有其他依赖项移出到父../node_modules文件夹中。 这将起作用,因为 NodeJS CommonJS 模块系统的工作方式是向上移动到父目录,依此类推,直到到达树的根目录。 请参阅: https ://nodejs.org/api/modules.html

  • 或者 gitignore 所有/node_modules/*除了你的/node_modules/your-modules 请参阅: Make.gitignore 忽略除少数文件外的所有内容

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM