Чи потрібно перевірити node_modules, щоб git під час створення програми node.js на Heroku?


368

Я дотримувався основних інструкцій щодо початку роботи для 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: 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?


10
Я є власником мови вузла в Heroku, і відповідь проста: Ні. Не node_modulesзаходьте в додатки Heroku.
hunterloftis

@hunterloftis "Не перевіряти node_modules в " або "Не перевіряти node_modules в "? Щоб уточнити, як власник мови вузла в Heroku, ви хочете, щоб ми завантажили всі наші node_modules через наш git push чи ні? Я вважаю за краще не через втрату пропускної здатності та те, що Heroku отримає їх на задній план мого git push; однак мені довелося редагувати файли в своїх модулях node_ вручну, щоб заставити Heroku завантажити мій додаток. Тому мені довелося ігнорувати node_modules мінус весь модуль, який включав мій відредагований файл, щоб змусити його працювати.
ZStoneDPM

Відповіді:


400

Друге оновлення

Поширені питання більше не доступні.

З документації shrinkwrap:

Якщо ви хочете заблокувати конкретні байти, що входять до пакету, наприклад, щоб мати 100% впевненість у можливості відтворення розгортання або побудови, то вам слід перевірити свої залежності в керуванні джерелами або застосувати інший механізм, який може перевірити. вміст, а не версії.

Шеннон і Стівен згадували про це раніше, але я думаю, це має бути частиною прийнятої відповіді.


Оновлення

Джерело, вказане для наведеної нижче рекомендації , оновлено . Вони більше не рекомендують виконувати node_modulesпапки.

Зазвичай ні. Дозвольте npm вирішувати залежності для ваших пакетів.

Для пакунків, які ви розгортаєте, таких як веб-сайти та програми, слід використовувати npm shrinkwrap, щоб заблокувати ваше повне дерево залежності:

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


Оригінальна публікація

Для довідки, npm FAQ чітко відповідає на ваше запитання:

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

і для того, щоб зробити це хорошим обґрунтуванням, прочитайте допис Мікеля Роджерса про це .


Джерело: https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git


13
Це не правильно - насправді це дуже погана ідея. Якщо ви розвиваєтеся в Windows, а потім розгортаєтеся в Linux, вам потрібно буде відновити node_modules під час розгортання. Що означає - хаос. Багато модифікованих файлів, і не уявляю, що робити.
користувач3690202

8
Це неможливо - одні наші розробники розробляють вікна націлювання, інші націлюють на Linux, але та сама база коду. Найкращим підходом було б не фіксувати вузлові модулі - oops.
користувач3690202

7
@ user3690202 Здається, що у вас є дуже нетрадиційний випадок, а не норма, тому сказати "це неправильно", ймовірно, завищення. Сказавши це, не впевнений, у чому полягає ваш конкретний випадок використання, але я не можу придумати жодної причини використання як Windows, так і Linux для розробки. Дотримуйтесь одного і запустіть тести або QA на всіх ваших платформах.
Костя

16
@Kostia Наш випадок використання є досить поширеним. Ми є добровольцями та використовуємо власні машини, а не фірмові. Схоже, досить поширена ситуація з відкритим кодом.
Адам

4
@Adam дотично, ви можете додати файли, що компілюються .gitignore? Таким чином, джерело знаходиться в git, і ніяких складених компонентів немає, подібно до того, як distабо outputпапки gitignored у grunt та gulp проектах.
Костя

160

Моє найбільше занепокоєння щодо не перевірки node_modulesна git полягає в тому, що через 10 років в дорозі, коли ваша виробнича заявка все ще використовується, npm може не бути поруч. Або npm може пошкодитися; або сервіси можуть вирішити видалити бібліотеку, на яку ви покладаєтесь, зі свого сховища; або версія, яку ви використовуєте, може бути оброблена

Це можна пом'якшити у менеджерів репо, як-от maven, тому що ви завжди можете використовувати свій власний локальний Nexus або Artifactory, щоб підтримувати дзеркало з пакунками, які ви використовуєте. Наскільки я розумію, така система не існує для npm. Те саме стосується клієнтів, що керують бібліотеками, як Bower та Jamjs.

Якщо ви присвятили файли власному git repo, тоді ви можете їх оновлювати, коли вам подобається, і у вас є комфорт повторюваних збірок і знання про те, що ваша програма не порушиться через якісь сторонні дії.


10
Сьогодні багато варіантів: 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 ) тощо
Йоганн

4
Цитата від npmjs FAQ: "Якщо ви параноїчні щодо залежної від екосистеми npm, вам слід запустити приватне дзеркало npm або приватний кеш.". Я думаю, це вказує на питання, на яке ви звертаєтесь, правда?
Тейлан


2
Нм не знищується протягом ночі, тому користь насправді не поєднується зі втратою ясності в історії ваших зобов’язань та вашим величезним розміром пакету. Якщо хтось створює додаток, який, на їхню думку, все ще буде активним через 10 років, розумно розраховувати, що він отримає багато технічного обслуговування по дорозі. Суть щодо відключення NPM є набагато кращим аргументом, хоча, мабуть, є кращі способи зменшити цей ризик, ніж зобов'язання з джерелом.
Сем П

3
Навіть місяць на дорозі небезпечний, якщо ви не здійснюєте свої залежності (хоча краще в окремому сховищі). Як я виявив одного ранку, коли я клонував один із своїх проектів і виявив, що версія пакету була видалена з npm. Я витратив пів дня на зміну всіх моїх версій каскадних залежностей, щоб отримати оновлення npm для роботи та створення заново.
Річард

67

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

Якщо node_modules:

  • існує, тоді npm installвикористовуватиме надані ліцензії та відновить будь-які бінарні залежності npm rebuild.
  • не існує, тоді npm installдоведеться добирати всі залежності, що додає час кроку компіляції слимаків.

Дивіться джерело зборки Node.js для цих точних кроків

Однак оригінальна помилка виглядає як несумісність між версіями npmта node. Бажано завжди чітко встановлювати enginesрозділ вашого packages.jsonвідповідно до цього посібника, щоб уникнути таких ситуацій:

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

Це забезпечить паритет розробки / скорочення та зменшить ймовірність таких ситуацій у майбутньому.


Дякую за допомогу, Райан. Це мене пережило помилку версії npm, але тепер вона не спрацьовує при компіляції пакета redis Повідомлення про помилку - "OSError: [Errno 2] Немає такого файлу чи каталогу: '/ Користувачі / Jason / tastemade / tastebase / node_modules / redis-url / node_modules / redis / node_modules / hiredis / build'". Схоже, він використовує шлях від моєї локальної скриньки на серверах heroku. Чи є певні файли в node_modules, які мені потрібно додати до .gitignore?
Джейсон Гріффін

Я не впевнений, що відбувається з цією конкретною бібліотекою, але я б спробував у цьому випадку виключити node_modules з git і побачити, чи це допомагає (змушуючи npm добирати все саме і забезпечувати свіжу середу побудови).
Ryan Daigle

@RyanDaigle Краща практика в даний час (листопад 2013) , рекомендований як НПМ ( npmjs.org/doc / ... ) і Heroku ( devcenter.heroku.com/articles / ... ), щоб перевірити в node_modules мерзотнику. Ви б оновили свою відповідь (оскільки вона має найвищі рахунки)?
Тім Діггінс

Під час натискання на heroku ви отримаєте вихід "-----> Каталог node_modules кешування для майбутніх збірок". Це дозволяє скоротити майбутню компіляцію слизів.
ph3nx

У мене проблема, що шлях файлу node_modules занадто довгий для здійснення. Гіт не знайде файли.
Код фараона

22

Я збирався залишити це після цього коментаря: Чи потрібно перевірити в 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

Переконайтесь, що файли не змінені.


Просто додав це. Вирішили мою проблему. Windows github продовжував збої, намагаючись перейти понад 7000+ файлів node_module: /
Бетмен

10

Я вважаю, що npm installне слід працювати у виробничих умовах. Є кілька речей, які можуть піти не так - відключення npm, завантаження нових залежностей (стискання, здається, це вирішило) - це дві з них.

З іншого боку, node_modulesне слід вчиняти на git. Окрім великого розміру, доручення, включаючи їх, можуть стати відволікаючими.

Найкращими рішеннями були б такі: npm installслід працювати в умовах ІС, подібних виробничому середовищу. Усі тести будуть запущені, і буде створений файл з випущеним на блискавки, який буде включати всі залежності.


Чому б у вас був крок, який працює на CI, який не запускається як частина вашого розгортання? Це означає, що ви не маєте паритету між двома системами! Як зазначено у відповіді вище - виконайте папку, просто ігноруйте нативні розширення, таким чином ви охоплені такими речами, як відключення npm
Voycey

1
Дякуємо за ваш коментар Я вважаю, що node_modules, що запускаються на вашому виробничому сервері, повинні генеруватися з npm установки, а не з того, що зробили розробники. Папка node_modules dev не обов'язково відповідає вмісту package.json.
користувач2468170

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: ваш / виділений / node_modules / git / repository.git]

Він обчислить хеш вашого пакета package.json і перевірить вміст node_modules з віддаленого репо, або, якщо це перша збірка для цього пакета.json, виконає чистку npm installі підштовхне результати до віддаленого репо.


5

Що для мене працювало, явно додав версію npm до package.json ("npm": "1.1.x") і НЕ перевіряв node_modules для git. Розгортання може бути повільніше (оскільки він завантажує пакунки щоразу), але я не міг змусити їх складати, коли вони були зареєстровані. Heroku шукав файли, які існували лише у моїй локальній скриньці.


Якщо ви вважаєте, що моя відповідь була правильною, прийміть її, будь ласка? Дякую!
Райан Дайгл

У випадку, якщо це все ще до дискусій, я би поглянув на цей пост stackoverflow, який майже є дублікатом вашого вищезазначеного питання: stackoverflow.com/questions/11459733/… В основному, здається, умовою є перевірка в node_modules, і керуйте своїми версіями цих модулів локально. Це здається досить розумним, і, мабуть, найсміливішим поясненням є таке: mikealrogers.com/posts/nodemodules-in-git.html Удачі!
воїнпоштам

3

Замість того, щоб перевіряти в node_modules, зробіть файл package.json для своєї програми.

Файл package.json визначає залежності вашої програми. Потім Heroku може сказати npm, щоб встановити всі ці залежності. Підручник, до якого ви пов’язані, містить розділ про файли package.json.


У мене є package.json. Він має таке: {"name": "node-example", "version": "0.0.1", "залежності": {"express": "2.5.x", "redis-url": "0.1. 0 "," mongodb ":"> = 0.9.9 "}," двигуни ": {" вузол ":" 0.8.x "}}
Джейсон Гріффін

Я зробив у своєму локальному вікні, щоб створити каталог node_modules. Це те, що я зареєстрував, потім видалив, а потім додав назад.
Джейсон Гріффін

Якщо детальніше подивитись на підручник, здається, що вони виконують модулі node_. У такому випадку я не впевнений, чи є спосіб не зробити node_modules. Вибачте
matzahboy

3

Я використовую це рішення:

  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

  1. Створіть посилання від конкретної платформи node_modulesдо node_modulesкаталогу та додайте node_modulesдо .gitignore.
  2. Біжи npm install.
  3. Здійснення змін у сховищах субмодулів.
  4. Внесіть зміни у сховище вашого проекту.

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


3

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

Редагувати: оригінальне посилання було саме цим, але воно тепер мертве. Дякуємо @Flavio за вказівку на це.

Для резюме.

  • Перевіряйте лише node_modules для застосованих вами програм, не підтримуваних ними пакетів.
  • Будь-які компільовані залежності повинні мати перевірене джерело, а не цілі компіляції та $ npm відновитись при розгортанні.

Моя улюблена частина:

Всі ви, люди, які додали node_modules до вашого gitignore, видаліть це лайно, сьогодні це артефакт епохи, яку ми надто раді залишити. Ера глобальних модулів мертва.


Веб-сайт, який ви пов’язали, здається, термін дії його закінчився, і він зараз наповнений шахрайськими оголошеннями. Я хотів би, щоб ці оголошення були "артефактами епохи, яку ми всі були б дуже раді залишити".
Флавіо справляється

1
@FlavioCopes Оновив свою відповідь за посиланням від Wayback Machine.
Бенджамін Крозьє

2

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

[...] вузол починається з батьківського каталогу поточного модуля, додає /node_modulesта намагається завантажити модуль з цього місця.

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

Якщо ви прокатуєте власні модулі, характерні для вашої програми, ви можете зберігати ці ( і лише ті ) у своїх програмах /node_modules. І перемістіть усі інші залежності до батьківського каталогу.

Цей випадок використання досить приголомшливий, він дозволяє вам зберігати модулі, які ви створили спеціально для вашої програми, гарно з вашим додатком, і не захаращує ваш додаток залежностями, які можна встановити пізніше.


1

сценарій 1:

Один сценарій: Ви використовуєте пакет, який видаляється з npm. Якщо у вас є всі модулі в папці node_modules, це не буде для вас проблемою. Якщо ви маєте лише ім'я пакета у package.json, ви більше не можете його отримати. Якщо пакет менше 24 годин, ви можете легко вийняти його з npm. Якщо це старше 24 годин, то вам потрібно зв’язатися з ними. Але:

Якщо ви звернетесь до служби підтримки, вони перевірять, чи не призведе до видалення цієї версії вашого пакета будь-які інші встановлення. Якщо це так, ми його не будемо видаляти.

читати більше

Тож шанси на це низькі, але є сценарій 2 ...


сценарій 2:

Інший сценарій, коли це так: Ви розробляєте корпоративну версію свого програмного забезпечення або дуже важливого програмного забезпечення та записуєте у свій package.json:

"dependencies": {
    "studpid-package": "~1.0.1"
}

Ви використовуєте метод function1(x)цього пакету.

Тепер розробники studpid-пакету перейменовують метод 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 Мб) до вашого сховища, обійдеться вам у пам'яті. Кілька кб (лише пакет.json) порівняно із сотнями МБ (package.json & node_modules) ... Подумайте про це.

Ви могли це зробити / повинні подумати про це, якщо:

  • програмне забезпечення дуже важливе.

  • це коштує вам грошей, коли щось не вдається.

  • ви не довіряєте реєстру npm. npm є централізованим і теоретично може бути вимкнено.

Вам не потрібно публікувати папку node_modules у 99,9% випадків, якщо:

  • ви розробляєте програмне забезпечення лише для себе.

  • ви щось запрограмували і просто хочете опублікувати результат на GitHub, тому що хтось інший може бути зацікавлений у цьому.


Якщо ви не хочете, щоб node_modules знаходилися у вашому сховищі, просто створіть .gitignoreфайл і додайте рядок node_modules.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.