首页 文章

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

提问于
浏览
343

我在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(来源)

它指示我将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存储库处于不良状态?

11 回答

  • 20

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

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

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

  • 3

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

    • 创建包含 node_modules 的单独存储库 . 如果您具有应为特定平台构建的本机模块,则为每个平台创建单独的存储库 .

    • 使用 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

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

    • 运行 npm install .

    • 提交子模块存储库更改 .

    • 提交项目存储库更改 .

    因此,您可以在不同平台上轻松切换 node_modules (例如,如果您在OS X上进行开发并部署到Linux) .

  • 1

    http://nodejs.org/api/modules.html

    [...]节点从当前模块的父目录开始,并添加/ node_modules,并尝试从该位置加载模块 . 如果在那里找不到它,那么它将移动到父目录,依此类推,直到到达树的根目录 .

    如果您正在滚动自己的应用程序特定模块,则可以将这些(并且只有那些)保留在应用程序的 /node_modules 中 . 并将所有其他依赖项移出到父目录 .

    这个用例非常棒,它可以让你保留专门为你的应用程序创建的模块与你的应用程序,并不会使你的应用程序混乱与以后可以安装的依赖项 .

  • 64

    第二次更新

    常见问题解答不再可用 .

    shrinkwrap的文档:

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

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


    更新

    列出的来源为以下建议has been updated . 他们不再建议提交 node_modules 文件夹 .

    通常,没有 . 允许npm解析包的依赖关系 . 对于您部署的软件包(例如网站和应用程序),您应该使用npm shrinkwrap来锁定完整的依赖关系树:https://docs.npmjs.com/cli/shrinkwrap


    原帖

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

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

    对于一些很好的理由,请阅读Mikeal Rogers' post on this .


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

  • 7

    您不应该在 .gitignore 中包含 node_modules (或者更确切地说you should include node_modules in your source已部署到Heroku) .

    如果 node_modules

    • exists 然后 npm install 将使用那些托管的库,并将使用 npm rebuild 重建任何二进制依赖项 .

    • doesn't exist 然后 npm install 将必须获取所有依赖项本身,这为slug编译步骤增加了时间 .

    请参阅Node.js buildpack源代码these exact steps

    但是,原始错误看起来是 npmnode 版本之间的不兼容性 . 根据this guide始终显式设置 packages.jsonengines 部分是个好主意,以避免出现以下类型的情况:

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

    这将确保dev/prod parity并减少将来发生此类情况的可能性 .

  • 2

    我一直在使用提交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 并将结果推送到远程仓库 .

  • 8

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

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

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

  • 377

    对我有用的是明确地将一个npm版本添加到package.json(“npm”:“1.1.x”)而不是将node_modules检入git . 部署速度可能较慢(因为每次都会下载软件包),但在签入时我无法编译软件包.Heroku正在查找仅存在于本地邮箱中的文件 .

  • 150

    来自https://web.archive.org/web/20150212165006/http://www.futurealoof.com/posts/nodemodules-in-git.html

    编辑:原始链接是this one但它现在已经死了 . 谢谢@Flavio指出来了 .

    回顾一下 . 只检查部署的应用程序的node_modules,而不是您维护的可重用软件包 . 任何已编译的依赖项都应该检入它们的源,而不是编译目标,并且应该在部署时进行$ npm重建 .

    我最喜欢的部分:

    所有那些将node_modules添加到你的gitignore的人,删除那个狗屎,今天,这是一个我们都很乐意留下的时代的神器 . 全球模块的时代已经过去 .

  • 2

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

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

  • 2

    在此评论之后我打算离开这个:Should I check in node_modules to git when creating a node.js app on Heroku?

    但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
    

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

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

    确保没有更改文件 .

相关问题