Должен ли я использовать node_modules для git при создании приложения node.js на Heroku?

324

Я выполнил основные инструкции по началу работы для node.js на Heroku здесь:

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

В этой инструкции не указывается, что вы создаете .gitignore node_modules, и поэтому подразумеваете, что node_modules должен быть установлен в git. Когда я включаю node_modules в git, мое приложение для запуска запускается правильно.

Когда я выполнил более продвинутый пример:

https://devcenter.heroku.com/articles/realtime-polyglot-app-node-ruby-mongodb-socketio https://github.com/mongolab/tractorpush-server (источник)

Он поручил мне добавить node_modules в .gitignore. Поэтому я удалил node_modules из git, добавил его в .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: [email protected] || 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: [email protected] || 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?

  • 6
    Я владелец языка Node в Heroku, и ответ прост: Нет. Не node_modules в приложения Heroku.
Теги:
npm
heroku
gitignore

11 ответов

373
Лучший ответ

Второе обновление

ЧаВо больше не доступно.

Из документации shrinkwrap:

Если вы хотите заблокировать определенные байты, включенные в пакет, например, чтобы иметь 100% уверенность в возможности воспроизвести развертывание или сборку, тогда вы должны проверить свои зависимости в исходном контроле или преследовать какой-то другой механизм который может проверять содержимое, а не версии.

Шеннон и Стивен упомянули об этом раньше, но я думаю, что это должно быть частью принятого ответа.

Update

Обновлен источник, указанный в приведенной ниже рекомендации . Они больше не рекомендуют устанавливать папку node_modules.

Обычно нет. Разрешить npm разрешать зависимости для ваших пакетов.

Для развертываемых пакетов, таких как веб-сайты и приложения, вы должны использовать npm shrinkwrap, чтобы заблокировать ваше полное дерево зависимостей:

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


Оригинальное сообщение

Для справки, npm FAQ отвечает на ваш вопрос четко:

Проверьте node_modules на git на вещи, которые вы развертываете, например на веб-сайтах и приложения. Не проверяйте node_modules на git для библиотек и модулей предназначенные для повторного использования. Используйте npm для управления зависимостями в своем dev среде, но не в сценариях развертывания.

и для некоторого хорошего объяснения для этого, прочитайте сообщение Майкеля Роджерса на этом.


Источник: https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git

  • 9
    Это не правильно - на самом деле это очень плохая идея. Если вы разрабатываете для Windows, а затем развертываете в Linux, вам потребуется перестроить node_modules при развертывании. Что значит - хаос. Много модифицированных файлов, и не знаю, что делать.
  • 1
    @ user3690202 ваш скрипт развертывания должен просто запустить npm rebuild .
Показать ещё 15 комментариев
155

Моя самая большая забота о том, чтобы не проверять node_modules на git, - это то, что 10 лет в будущем, когда ваше производственное приложение все еще используется, npm может не быть рядом. Или npm может стать поврежденным; или сопровождающие могут решить удалить библиотеку, на которую вы полагаетесь, из своего репозитория; или версия, которую вы используете, может быть обрезана.

Это можно смягчить с помощью менеджеров репо, таких как maven, потому что вы всегда можете использовать свой собственный локальный Nexus или Artifactory, чтобы поддерживать зеркало с используемыми вами пакетами. Насколько я понимаю, такой системы не существует для npm. То же самое касается менеджеров библиотек на стороне клиента, таких как Bower и Jamjs.

Если вы перенесли файлы на свой собственный репозиторий git, тогда вы можете обновлять их, когда захотите, и у вас есть удобство повторяемых сборок и знания о том, что ваше приложение не будет ломаться из-за каких- партийного действия.

  • 8
    Сегодня множество вариантов: Nexus ( Issues.sonatype.org/browse/NEXUS-5852 ), Artifactory ( jfrog.com/jira/browse/RTFACT-5143 ), npm_lazy ( github.com/mixu/npm_lazy ), npm-lazy- зеркало ( npmjs.org/package/npm-lazy-mirror ) и т. д.
  • 0
    Не могу согласиться больше.
Показать ещё 8 комментариев
65

Вы не должны включать node_modules в .gitignore (или, скорее, вы должны включить node_modules в свой источник, развернутый в Heroku).

Если node_modules:

  • существует, тогда npm install будет использовать эти выпущенные libs и будет восстанавливать любые двоичные зависимости с помощью npm rebuild.
  • не существует, тогда npm install придется извлекать все зависимости, которые добавляют время на этап компиляции slug.

Смотрите Node.js buildpack source для этих точных шагов

Однако исходная ошибка выглядит несовместимой между версиями npm и node. Рекомендуется избегать таких ситуаций: engines раздел packages.json в соответствии с этим руководством.

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

Это обеспечит dev/prod parity и уменьшит вероятность подобных ситуаций в будущем.

  • 0
    Спасибо за помощь Райан. Это помогло мне избежать ошибки версии npm, но теперь она не работает при компиляции пакета redis. Сообщение об ошибке: «OSError: [Errno 2] Нет такого файла или каталога: '/ Users / Jason / tastemade / tastebase / node_modules / redis-url / node_modules / redis / node_modules / hiredis / build'». Похоже, он использует путь из моего локального ящика на серверах heroku. Есть ли определенные файлы в node_modules, которые мне нужно добавить в .gitignore?
  • 0
    Я не уверен, что происходит с этой конкретной библиотекой, но я бы попробовал исключить node_modules из git в этом случае и посмотреть, поможет ли это (принудительно заставляя npm извлекать все самому и обеспечивая новую среду сборки).
Показать ещё 5 комментариев
20

Я собирался оставить это после этого комментария: Должен ли я проверить node_modules на git при создании приложения node.js на 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

Убедитесь, что файлы не изменены.

  • 0
    Просто добавил это. Решил мою проблему. Windows github продолжала падать, пытаясь перебрать 7000+ файлов node_module: /
  • 0
    хороший список файлов .gitignore. может быть полезно для вас.
7

Я считаю, что npm install не должен запускаться в рабочей среде. Есть несколько вещей, которые могут пойти не так - npm отключить, загрузка новых зависимостей (shrinkwrap, похоже, решила это) - это два из них.

С другой стороны, node_modules не следует указывать на git. Помимо их большого размера, коммиты, включая их, могут стать отвлекающими.

Лучшие решения будут такими: npm install должен работать в среде CI, которая похожа на производственную среду. Все тесты будут запущены, и будет создан файл с zip-релизом, который будет содержать все зависимости.

  • 0
    Почему у вас есть шаг, который выполняется на CI, который не будет выполняться как часть вашего развертывания? Это означает, что у вас нет паритета между двумя системами! Как сказано в ответе выше - коммит папки просто игнорирует нативные расширения, таким образом, вы покрыты такими вещами, как сбои в работе npm
  • 1
    Спасибо за ваш комментарий. Я считаю, что node_modules, которые запускаются на вашем производственном сервере, должны генерироваться из npm-инсталляции, а не из того, что разработчики сделали. Папка dev_modules разработчика не обязательно соответствует содержимому package.json.
7

Я использую как фиксацию папки node_modules, так и термоусадочную упаковку. Оба решения не сделали меня счастливым.

Короче: commit node_modules добавляет слишком много шума в репозиторий.
И shrinkwrap.json нелегко управлять, и нет никакой гарантии, что некоторые проекты, упакованные в термоусадочную пленку, будут построены через несколько лет.

Я обнаружил, что Mozilla использует отдельный репозиторий для одного из своих проектов https://github.com/mozilla-b2g/gaia-node-modules

Поэтому мне не потребовалось много времени, чтобы реализовать эту идею в инструменте node CLI https://github.com/bestander/npm-git-lock

Перед каждой сборкой добавьте npm- git -lock --repo [git @bitbucket.org: ваш/посвященный/node_modules/git/repository.git]

Он рассчитает хэш вашего пакета .json и либо проверит содержимое node_modules с удаленного репо, либо, если это первая сборка для этого пакета .json, он сделает чистый npm install и нажмет результаты удаленного репо.

3

Что работало для меня, явным образом добавлял версию npm для package.json( "npm": "1.1.x" ) и НЕ проверяла в node_modules на git. Он может быть медленнее для развертывания (поскольку он загружает пакеты каждый раз), но я не мог получить пакеты для компиляции, когда они были проверены. Heroku искал файлы, которые существовали только в моем локальном поле.

  • 0
    Если вы считаете, что мой ответ был правильным, пожалуйста, примите его? Спасибо!
  • 0
    В случае, если это все еще подлежит обсуждению, я бы взглянул на этот пост stackoverflow, который является почти дубликатом вашего вопроса выше: stackoverflow.com/questions/11459733/… По сути, кажется, что соглашение состоит в том, чтобы проверять в node_modules, и управлять вашими версиями этих модулей локально. Это кажется довольно разумным, и, возможно, самое краткое объяснение таково: mikealrogers.com/posts/nodemodules-in-git.html Удачи!
2

Я использую это решение:

  • Создайте отдельный репозиторий, содержащий 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

  1. Создайте ссылку из специфичного для платформы каталога node_modules to node_modules и добавьте node_modules в .gitignore.
  2. Запустите npm install.
  3. Изменять изменения в подменю подменю.
  4. Зафиксируйте изменения в репозитории проекта.

Таким образом, вы можете легко переключаться между node_modules на разных платформах (например, если вы разрабатываете OS X и развертываете в Linux).

2

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

Изменение: оригинальная ссылка была этой, но теперь она мертва. Спасибо @Flavio за указание на это.

Напомним.

  • Только checkin node_modules для приложений, которые вы развертываете, а не повторно используемых пакетов, которые вы поддерживаете.
  • Любые скомпилированные зависимости должны проверять исходный код, а не цели компиляции, а при развертывании - $ npm rebuild.

Моя любимая часть:

Все, кого вы добавили node_modules в ваш gitignore, удалите это дерьмо, сегодня, его артефакт эпохи, были слишком счастливы оставить позади. Эпоха глобальных модулей мертва.

  • 0
    Сайт, на который вы ссылались, похоже, просрочен и теперь полон мошеннической рекламы. Я хотел бы, чтобы эти объявления были «артефактами эпохи, которую мы все были бы слишком счастливы оставить позади».
  • 1
    @FlavioCopes Обновил мой ответ со ссылкой с Wayback Machine.
2

Вместо проверки в node_modules создайте файл package.json для своего приложения.

В файле package.json указаны зависимости вашего приложения. Затем Heroku может указать npm для установки всех этих зависимостей. В учебнике, в котором вы были связаны, содержится раздел о файлах package.json.

  • 0
    У меня есть package.json. Он имеет следующее: {"name": "node-example", "version": "0.0.1", "dependencies": {"express": "2.5.x", "redis-url": "0.1. 0 "," mongodb ":"> = 0.9.9 "}," engine ": {" node ":" 0.8.x "}}
  • 0
    Вы запускали команду установки npm?
Показать ещё 2 комментария
1

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

[...] node начинается с родительского каталога текущего модуля и добавляет /node_modules и пытается загрузить модуль из этого места.

Если он там не найден, , то он перемещается в родительский каталог и т.д., пока не будет достигнут корень дерева.

Если вы загружаете свои собственные модули, специфичные для вашего приложения, вы можете сохранить их (и только те) в своем приложении /node_modules. И переместите все другие зависимости в родительский каталог.

Этот пример использования довольно увлекательный, он позволяет вам создавать модули, созданные специально для вашего приложения, с вашим приложением, и не загромождает ваше приложение с зависимостями, которые могут быть установлены позже.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню