Comments 115
— Чувак *** — прошлый век, сейчас 2017 год, все используют Yarn!
От NuGet как менеджера или от паблик реестра пакетов?
А с nuget-то что не так? И чем заменили?
А эти же 600 МБ теперь тоже тянутся, но из VCS?
А мы наоборот пришли к схеме с приватными репозиториями и живём счастливо.
Т.е. есть dev/qa/production ветки, откуда берутся пакеты при сборке на соответствующей среде и ещё есть shared ветка, куда руками ответственных людей перекладываются пакеты из nuget.org. Все ci-сервера смотрят только на локальные ветки. Таким образом трафик только локальный, все билды используют только approved-пакеты и не в состоянии "случайно" использовать какой-то не такой пакет.
Т.е. разработчик в новом проекте, конечно, может взять что угодно из nuget.org, но первый же билд на dev-среде упадёт и ему придётся "защищать" используемые пакеты, чтоб их втащили на shared.
Меньше велосипедов, унификация компонентов и тд…
В рамках VCS все legacy-связи потихоньку отрезаются и переводятся на пакеты. Проблем в разы меньше становится.
Коммитить всё в репозиторий — это имеется ввиду, что зависимости прям тут же бинарниками лежат и таскаются тоннами при чекаутах? Отличное решение, чо. Как помножил это всё на количество проектов — как-то даже страшновато стало. Чтоб когда ci-билд тригерится на каждый коммит, а чекаут тащит всё это барахло — эти люди ещё что-то про трафик будут говорить?
600 МБ зависимостей каждый раз перекачивать через наци-компанию надоело
Я не знаком с NuGet, поэтому может задам глупый вопрос.
У NuGet нет такого же локального кэша, как, например, у Maven?
Похоже фейсбук решил окончательно захватить мир. Помнится лет 5 назад в плане опенсорса я вообще ничего о них не слышал, а сейчас React, GraphQL, Atom, Yarn, ещё целая куча всякого интересного. Молодцы в общем))
В случае NPM, в зависимости от подключенных модулей, каталог node_modules мог сильно отличаться от машины к машине.
А они как хотели, чтоб он был везде одинаковый, независимо от подключенных модулей?)
Если честно, я был уверен, что npm install при существующем package.json дает идемпотентный результат. Если речь о том, что можно нечаянно обновиться на минорную версию (и напороться на неминорные изменения), так версии можно жестко фиксировать.
В случае небольших команд, занимающихся разработкой, подобная кастомизация может и быть приемлемой, однако не в случае огромной DevOps-команды Facebook.
Мне искренне интересно, какие такие у них с npm проблемы возникли. Вроде бы npm install react --save
— не rocket science, не?
Множественные репозитории, retry on fail, кэширование установленных пакетов — это все мило, но не киллер-фича.
Это проблему должен был решить shrinkwrap замораживая всё дерево зависимостей — но с ним проблема, что он по разному на каждой системе генерируется + избыточный формат (у нас был на 3 мегабайта json + дифы не читались в принципе если чтото обновляешь минорное или даже перегенерируешь + падает переодически с неочевидными ошибками)
Понятно, спасибо. Я не сталкивался с проблемами зависимостей 2 порядка.
А я сталкивался и не один раз. Но самом деле можно делать оверрайд зависимостей второго порядка (неявных) и также фиксировать версии — Shrinkwrap, но это неудобно очень (конфиг файл большой). Я делаю немного по другому (кешрую весь каталог nmp_moules, для этого есть готовые тулзы всякие) ну и всегда указываю версии явно без всяких ~^ и тд.
А я сталкивался и не один раз.
А расскажите? Чтоб я знал, к чему готовиться.
Проблема возникает когда какой-нибудь модуль прописывает свои зависимости используя Semantic Versioning range фичи (^~ и прочий бред). В итоге возникают ситуации когда модуль тянет новую версию по неявно указанной зависимости, версию с которой он не способен работать нормально.
Пример https://github.com/miickel/gulp-angular-templatecache/issues/124 Вот фикс https://github.com/miickel/gulp-angular-templatecache/pull/125/commits/9c306a3898f7f33c0f55d5a909119fe5126e918d
Использую гугл сможете найти много информации о том что указание неявной версии зависимостей (чифа Semantic Versioning) это плохая практика.
"gulp-header": "1.x"
указание неявной версии зависимостей
Теперь понятно, почему я с этим никогда не сталкивался:)
Не обязательно так вот жестко в виде 1.x, бывают и другие сайд эффекты.
Более того видно что например "gulp-util": "3.x" так и остался с указанием неявной версии https://github.com/miickel/gulp-angular-templatecache/pull/125/commits/9c306a3898f7f33c0f55d5a909119fe5126e918d То есть они сделали фикс не осознавая проблемы целиком. Хотя в текущей мастер ветке версии уже указаны фиксировано что правильно — https://github.com/miickel/gulp-angular-templatecache/commit/9ddb88ab4fd778f641eb8e2c59ee2532ba3747d7#diff-b9cfc7f2cdf78a7f4b91a753d10865a2
То есть всегда следует указывать версии фиксированно, а обновлять верси руками (npm-check-updates помогает в этом).
На самом деле можно нормально использовать semantic version range.
Если автор библиотеки не релизит ее по semver, то его за это надо пинать.
В вашей конкретной ситуации виноват автор gulp-header, за то, что выпустил версию без обратной совместимости.
В качестве бонуса semver вы получаете простые багфиксы. Например нашелся баг в библиотеке A, от которой вы зависите через C -> B -> A. Из-за тривиального фикса, B и C тоже вынуждены релизить свои библиотеки. Гибкий диапазон версий избавляет от рутинного микроменеджмента. Если авторы следуют правилам, конечно.
Вы не так поняли, я не против использования semantic versioning в целом, но против использования его range фичей и неявного указания версий в зависимостях. Я убедился что в завиимостях всегда нужно указывать версии явно, всегда, и обновленния делать вручную (npm-check-updates помогает).
В вашей конкретной ситуации виноват автор gulp-header, за то, что выпустил версию без обратной совместимости.
Это был очень явный пример который я сразу поэтому и вспомнил, случай далеко не единичный. В том то и дело что благодаря использованию semantic versioning range фичей команда npm install не дает одинаковый результат при исполнении в разное время! По моему глубокому убеждения команда должна давать одинаковый результат и использования кеширования всего npm_modules каталога (допустим имя файла кеша берется по хешу от package.json) + явное указание версии приближает поведение исполнения команды к желаемуму поведению.
Если авторы следуют правилам, конечно.
Я не готов доверять всякой школоте в том что они следуют правилам, люди это слабые звенья систем, вы готовы им доверять пожалуйста а я лучше перестрахуюсь тк уже обжигался на собственном опыте.
А они как хотели, чтоб он был везде одинаковый, независимо от подключенных модулей?)наверное как в композере: composer.lock — файл со списком замороженных версий. Команда
composer install ставит версии прописанные в composer.lock не трогая его (если он был, конечно)
composer update — обновляет composer.lock и ставит последние подходящие под номенклатуру composer.json версии
В общем, судя по скриншотам из оригинальной статьи, я понял, что фэйсбуку просто не хватало сран вездесущих эмодзи в npm, а npm i -S
слишком долго набирать, yarn add
куда быстрее. Ну и ещё естественно npm обладал для них фатальным недостатком.
Важное отличие yarn, что он работает гораздо быстрее. Я проверил на рабочем проекте, он устанавливает модули за 30 секунд, а npm делал за 90.
npm install
сейчас занимает существенную долю времени билда, а тут ускорение в 3 раза, поэтому я раздумываю переехать на yarn, когда все немного поуляжется и основные косяки всплывут и пофиксятся.
То что быстро — это хорошо.
Однако оно видимо не умеет читать настройки из .npmrc
. У меня в этом файле прописан адрес локального репозитория для своих алиасов. Беглый осмотр доков ничего не дал. Так что пока заменить npm для меня оно точно не сможет.
pull-request уже в пути.
Это круто! — Отлить не успеешь.
Разве модули не ставятся в проект всего 1 раз, после клонировании репозитория?
Локально долгая установка не проблема.
Но во время билда, все ставится и собирается с нуля, поэтому быстрая установка == быстрый билд
Инкрементальные билды уже не в моде?..
И как инкрементальные билды спасут от долгой установки зависимостей? У меня фронтенд-проект, сборщики сами ставятся через npm, как и непосредственно и сами зависимости самого проекта. Конечно можно каждый раз не удалять node_modules из сборочной директории, но раз-два в месяц бывает, что локально всё собирается, а на сервере — нет. И это именно из-за разных версий пакетов.
Что такое инкрементальный билд?
Вообще, сохранять состояние воркспейса между билдами неправильно. Например, удалим модуль из декларации зависимостей, а на диске он останется жить и никто ничего не заметит, пока внезапно это не выстрелит. Поэтому только install с нуля, чтобы по-честному.
Решил проблему на нашем дженкинсе добавлением --cache-min Infinity
--cache-min Infinity не решает проблему, это большой костыль. Я тоже так начинал, но в итоге пришлось использовать сторонние тулзы для кешрования, я их кучу перепробывал — остановился на https://github.com/swarajban/npm-cache (интегрировал в Maven сборку).
Была довольно серьезная проблема с резолвом пакетов новых версий, но ее закрыли, кажется в 3.9. После этого обновления и еще добавления prune стало работать вполне сносно. У нас тоже maven как раз и что-то мне сильно не хотелось кэширующий прокси в процесс добавлять, с учетом того что сборка на дженкинсе и локальной ноды там нет и не сильно нужна.
Если снова вылезут проблемы — попробую npm-cache.
кэширующий прокси в процесс добавлять
Это один из вариантов стороннего кеширования, со своими минусами но и плюсами. Я для наших нужд делал большой анализ и тест решений, и остановился на том что выше указано.
PS npm-cache не содержит в себе сервер, это просто по сути копи паст каталога с архивированием.
Мы вот когда перешли на вебпак, время сборки выросло с 10 минут до 2 часов (ага)! После оптимизаций сократилось до 20 минут, из которых чистый нпм занимает ну примерно 6-7. Т.е. как бы лишние пару минут погоды то не сделают.
Но нет, даешь новый пакетный менеджер с котами и эмодзи!
PS извиняюсь за крики, накипело уже
Что именно у вас накипело?
У нас в команде воркфлоу с пулл-реквестами. И разработчики не любят ждать, когда отправили код на ревью, люди код посмотрели, а мерджить нельзя, все ждут билда.
Поэтому мы стараемся, чтобы тесты на пулл-реквест не занимали дольше 10 минут. Если будет на 2 минуты быстрее, то процессы заработают лучше, а производительность команды возрастет.
UPD накипело желание крупных игроков навязать свои инструменты вместо решения проблем существующих
Откуда столько боли? От необходимости поддерживать и npm, и bower на проектах, из-за того, что npm не умеет в семвер на гитхаб. Вот и опасаюсь, как бы не вышло, что нужно будет поддерживать еще один чудный пакетный менеджер.
Ну да, я параноик =(
Это примерно как если бы yum сделали не таким капризным ко сборкам из исходников, а то последний после установки чего-то из сорсов (и потом удаления всех упоминаний об этом) толком не ставит пакет: строчки ползут, ошибок нет, но и де-факто почти ничего не ставится. Ну, тут, вероятно, я чего-то не знаю о yum, тем не менее.
а не новое хранилищеЯ искренне надеюсь, что фейсбуку по душе npm-registry. Не дай бог, не дай бог.
npm ничего не тормазит присборке CI, просто кто-то не умеет (не хочет, не видит необходимости) кешровать модули грамотно.
А кешировать при билде что не позволяет? Для этого есть множество готовых тулов.
То, что кеширование это костыль?
Процесс npm install
должен быть однозначным и воспроизводимым. Кеширование node_modules усугубляет ситуацию.
По идее, кеширование модулей происходить где-то внутри npm, у него даже есть папка ~/.npm
с общим кешем модулей, только устанавливать быстрее это ему не помогает
Процесс npm install должен быть однозначным и воспроизводимым. Кеширование node_modules усугубляет ситуацию.
Должен быть но не все это понимают указывая зависимости неявным образом (с использвоанием ^~ и ид). Некоторые индивиды даже делают это в свои проектах, но проблемы также возникают когда сторонние модуль указывают зависимости неявным образом. Подумайте над этим и осознаете что процесс npm install абсолютно не является однозначно воспроизводимым при запуске в разное время.
Кроме этого некоторые модули имеюи бинарные зависимости, которые вытягиваются в зависимости от OS.
По идее, кеширование модулей происходить где-то внутри npm, у него даже есть папка ~/.npm с общим кешем модулей, только устанавливать быстрее это ему не помогает
Не по идее, это факт что npm имеет свой кеш, но он ОЧЕНЬ кривой.
Именно поэтому я рад появлению yarn с правильным кешем, который делает разворачивание node_modules c нуля очень быстрым и избавляет меня от дополнительных наворотов (за исключением самого yarn, но здесь замена npm -> yarn выглядит справедливой)
Нет, ведь зависимости могут добавляться/удаляться, их версии изменяются и т.д. А ещё полезно бывает время от времени удалять node_modules и ставить всё заново, так как иногда могут возникать странные вещи. Порой даже добавление 1-го пакета может занимать минуту.
В любом случае, если у этой штуки будет полная совместимость с npm, а скорость установки пакетов выше — то будет только лучше.
Хм. jspm уже закапывать? Я же только с voloBowernpm слез.
jspm немного другую задачу решает. Тут проблема в том, что метод разрешения зависимостей в nodejs требует несколько IO-операций, что нормально при синхронном подключении модулей и не очень — при асинхронном, как мы это делаем в браузере. jspm решает эту проблему, запоминая для каждого модуля его точку входа.
yarn про другое (а про что именно, пока что не очень понятно).
Кто сможет сказать, bower еще 2016 актуальный?
Забавно, что Фейсбук это как бы зло с социальной точки зрения, но с технологической точки зрения их основные продукты очень хороши и удобны. Они как бы говорят программисту: «Приходи на темную сторону, у нас есть крутые разработки»
Я правильно понял, что нужно только изменить npm install
на yarn install
?
Мой вебпак не сломается?
yarn global add gulp-cli
поставит вам gulp глобально
Документация: https://yarnpkg.com/en/docs/cli/global
и прощай yarn, там происходит какой-то эксепшен и приплыли.
Это неконструктивно. Я воспроизвел вашу проблему и зарепортил баг:
https://github.com/yarnpkg/yarn/issues/976
А что не так-то? Смысл Deprecated как раз в этом — так писать еще можно, но уже не рекомендуется.
Это была одна из проблем npm by design — можно партизански устанавливать пакеты без сохранения в package.json. Локально у разработчкика все работает, а другие члены команды этот модуль не видят.
Глобальная установка тоже нерекомендуемый паттерн. Все нужные для проекта CLI-утилиты можно устанавливать локально, они попадут в node_modules/.bin
. Более того, если у вас в package.json в секции scripts написано "test": "gulp test"
, то локально установленный gulp автоматически подложится в PATH, никакого оверхеда по сравнению с глобальным. В то время как на linux для глобальной установки нужен sudo, эта фича вообще спасение.
Так если речь идет о написании нового менеджера пакетов, то почему бы не сделать сразу нормально, с учетом проблем нынешнего cli.
Тем не менее, есть исключения. npm, yarn и bower лучше все же ставить глобально :)
Локально у разработчкика все работает, а другие члены команды этот модуль не видят.
Человек всегда слабое звено, любую систему можно поломать человеческой глупостью и отстствием ответственности. Кто на прописал все зависимости в package.json тому по рогам настучасть тк не понимает воркфлоу.
«перестаньте за меня думать» ©
В то время как на linux для глобальной установки нужен sudo, эта фича вообще спасение.
Только в случае установки node из репозитория.
Если ставить через nvm, то sudo уже не нужно, т.к. в этом случае node хранится в директории "~/.nvn/versions/"
Facebook и Google выпустили Yarn, новый менеджер пакетов для JavaScript