Comments 76
Почему эта фича не была добавлена? Наверняка обсуждения уже были, есть сторонние расширения, но нет из коробки. Если ответом было «by design», то очевидно, что единственный вариант — создание форка.
дистрибьютим зависимости внутри проекта после установки через git.
И что вы этом плохого? Ну кроме того, что "мне не нравится, что в моём репозитории лежит копия чужого кода".
Репозиторий распухает от такого. Недавно в чате ru.SO участник жаловался на медленную работу с полуторагигабайтным репозиторием...
Думаю у него была проблема не с полуторагигабайтным репозиторием, а с полуторагигабайтной рабочей копией. Потому как история на то и история, что кушать не просит, пока в неё не лезешь. Если же речь о том, что всё это долго выкачивается, то никто не заставляет выкачивать всю историю.
Зачем мне хранить в git зависимости, если я знаю, что введя команду npm install получу идентичное окружение? особенно учитывая, что на маленьком проекте node_modules будет превышать размер собственного кода в разы. Пример: установил create-react-app — 80 мб зависимостей, а собственно мой код не весит и 100 кб.
я хочу использовать систему контроля версий для контроля версий своего кода.
Сторонний код — такая же часть вашего приложения, как и ваш код. Вы видимо не застали такие эпики как dll-hell, rpm-hell, jar-hell и прочие dependency-hell?
Зачем мне хранить в git зависимости, если я знаю, что введя команду npm install получу идентичное окружение?
NPM доступен 24/7, пакеты никогда не удаляются, исходники без изменения версии никогда не меняются, бинарные модули не зависят от окружения, где собираются. Классно у вас там, наверно.
Пример: установил create-react-app — 80 мб зависимостей, а собственно мой код не весит и 100 кб.
Хороший повод не использовать create-react-app и тому подобные монструозные тулзы, которые ставятся по 5 минут, а делают всего ничего.
Сторонний код — такая же часть вашего приложения, как и ваш код.
да, но отличие в слове «сторонний» — я могу его получить со стороны другим способом, и то, что он часть моего проекта не есть аргумент в сторону хранения в гите
NPM доступен 24/7, пакеты никогда не удаляются, исходники без изменения версии никогда не меняются, бинарные модули не зависят от окружения, где собираются. Классно у вас там, наверно.
как только у меня будут с этим какие-то проблемы, отличные от гипотетических, я займусь их решением
Хороший повод не использовать create-react-app и тому подобные монструозные тулзы, которые ставятся по 5 минут, а делают всего ничего.это не монструозная тулза, а стандартный набор либ фронтендера на js. Сам я не фронтендер, и меня вполне устраивает подождать 2 минуты и приступить к написанию кода вместо компилирования кусочков знаний из статей в интернете
Можете до поры до времени. А потом случается казус и уже не можете.
Вы пропустили эпичный эпик с left-pad?
Вас обманули, это ни разу не стандартный набор. В js вообще мало чего стандартного. Я уверен полезной функциональности там на мегабайт максимум.
Вы пропустили эпичный эпик с left-pad?
не пропустил. это опять же недостаток npm-инфраструктуры, предусмотренный годы назад например в композере.
Вас обманули, это ни разу не стандартный набор. В js вообще мало чего стандартного. Я уверен полезной функциональности там на мегабайт максимум.
отставьте менторский тон. Я хоть и не фронтендер, но в js-инфраструктуре разбираюсь прекрасно.
Логирование, работа с сетью, реализация Virtual DOM, библиотека функций Lodas
И еще куча всего, что нужно для работы тех или иных пакетов
Если готов написать свой сборщик JS с HMR и CSS, рад буду использовать
А еще запилил свой аналог React
С Redux можешь не заморачиваться, он мало весит
Парсер JS
Сам по себе парсер бесполезен.
сборщик JS, Если готов написать свой сборщик JS с HMR и CSS, рад буду использовать
Сборщик JS и CSS. HMR вам не понадобится, ибо приложение загружается мгновенно.
компилятор JS, транслятор JS,
полифиллы JS
Лучше понифилы. Грамотные реализации много не едят.
оптимизация JS, минификация JS, сжатие JS
gzip с этим справляется эффективней.
реализация Virtual DOM, А еще запилил свой аналог React
Нафига? Есть подходы по интересней, чем перегенерировать дерево на каждый чих.
библиотека функций Lodas
Вы бы ещё jQuery вспомнили.
Логирование, работа с сетью
Логировнаие, работа с сетью и всё такое.
С Redux можешь не заморачиваться, он мало весит
Спасибо, ваше высочество :-)
толсто.
Вы пропустили эпичный эпик с left-pad?
нет, как и npm, больше такого не повторится с модулями старше 24 часов.
HMR вам не понадобится, ибо приложение загружается мгновенно.
HMR нужен не для быстрого перезапуска, а сохранения текущего стейта приложения. Особенно полезно при отладке большой формы, например.
gzip с этим справляется эффективней.
любая минификация перед сжатием, делает сжатый бандл меньше. А переодически и код ускоряет.
Вы бы ещё jQuery вспомнили.
иногда и jquery нужен, если маленький проектик на вечер и сроком жизни пару недель. А lodash все еще must have, особенно fp часть божественна.
толсто
Кто первый обвинит оппонента в толстоте — тот не тролль.
нет, как и npm, больше такого не повторится с модулями старше 24 часов.
Не повторится потому, что ___.
HMR нужен не для быстрого перезапуска, а сохранения текущего стейта приложения.
Для этого есть sessionStorage.
Особенно полезно при отладке большой формы, например.
А формы тем более по умолчанию должны выдерживать перезагрузку.
любая минификация перед сжатием, делает сжатый бандл меньше.
Ага, и стектрейсы с продакшена приходят тоже сильно короче. Профит от минификации минимален, а проблем вызывает море:
- Долгая сборка, из-за чего её отключают при разработке, из-за чего разработчик тестирует не в точности тот же код, что будет крутиться на проде.
- Без сорсмапов не разобраться что там происходит. А сорсмапы нужной версии не всегда есть или хотя бы легкодоступны.
- Отладчику даже с сорсмапами периодически сносит крышу.
иногда и jquery нужен, если маленький проектик на вечер и сроком жизни пару недель.
В этом случае нужен не jQuery, а тот инструмент, что лучше знаком. Мне проще из реактивных компонент собрать приложение, чем на jQuery вручную манипулировать деревом и ловить кучу багов рассинхронизации состояний.
А lodash все еще must have, особенно fp часть божественна.
Особенно божественно заниматься отладкой fp части, ага. Исполнение по шагам, условные точки останова, просмотр результата выполнения функции — всё это так удобно с так называемым fp, который к собственно функциональному программированию не имеет никакого отношения.
Вы видимо не застали такие эпики как dll-hell, rpm-hell, jar-hell и прочие dependency-hell?
Современные инструменты существуют, чтобы решать старые проблемы. Иначе зачем эти новые инструменты нужны?
Сторонний код — такая же часть вашего приложения, как и ваш код. Вы видимо не застали такие эпики как dll-hell, rpm-hell, jar-hell и прочие dependency-hell?Для всех перечисленных проблем есть нормальные решения. Взять хотя бы тот же Maven для Java.
на самом деле все ок и с таким подходом. есть npm rebuild.
Правда бывает, что бинарники под разные OS выкачиваются postinstall, так делает electron и nodegit, навскидку. Тут уже ничего не поделаешь с любым подходом.
Это очень плохо. Правда.
- Не все зависимости могут быть перенесены простым копированием папки node_modules, так как многие написаны например на С++, и требуют сборки. При этом, у разных разработчиков может быть не совместимое по ABI окружение или просто разные ОС.
- Многие пакеты при установке требуют выполнения lifecycle scripts про которые упоминается в статье. Естественно при копировании node_modules они не будут выполненны.
- package.json больше не является источником информации о действительно нужных зависимостях, все решает содержимое папки
- Учитывая все вышеперечисленное, а текже применяемую в npm методику дедупликации пакетов (когда вместо копирования одного и тогоже пакета, который является не прямой зависимостью он ложится в корень node_modules один раз) разрешение конфликтов в случае когда в одной версии модуль a удален, в другой модуль b обновлен или перемещен будет весьма веселым занятием
- Уже упомянутое распухание репозитория
Все вышеперечисленное актуально не только для ноды, проблема стара как мир, и правильным перешением является lock-файл.
Не все зависимости могут быть перенесены простым копированием папки node_modules, так как многие написаны например на С++, и требуют сборки.
Большинство модулей поставляются с пребилдами под популярные оси/архитектуры.
Многие пакеты при установке требуют выполнения lifecycle scripts про которые упоминается в статье.
Например? Вообще, на мой взгляд, это дурная практика.
package.json больше не является источником информации о действительно нужных зависимостях, все решает содержимое папки
Либо содержимое shrinkwrap.json. Кстати, типичная ситуация — кто-нибудь добавил модуль себе локально, но забыл добавить его в package.json — привет, падение в случайный момент.
Учитывая все вышеперечисленное, а текже применяемую в npm методику дедупликации пакетов
Это изначально была фиговая идея — ставить модули внутри, а не на одном уровне. Да, разные версии модулей тоже можно ставить на одном уровне. Пример, адекватной реализации — DUB.
в другой модуль b обновлен или перемещен будет весьма веселым занятием
Всё просто — разрешаем в любую сторону, а потом npm install.
Те самые пребилды выкачиваются обычно через lifecycle scripts. Можно конечно надеятся что они сложат их в node_modules, но как по мне — очень не надежно.
Примеры: ngrok, phantomjs, electron
А вот пример аддона для ноды, который нужно скомпилить при установке: node-proxy
Конечно, я согласен что стоит по возможности обходится без использования lifecycle scripts где это возможно, но они присутствуют в любом пакетном менеджере вплоть до apt. А вот действиительно плохой практикой является нарушение инкапсуляции работы пакетного менеджера.
Если ее не нарушать — все равно в какие папки и в сколько копий он кладет модули и выкачивает зависимости.
По поводу разрешения конфликтов я не понял. Т.е все равно, нужно хранить в актуальном виде package.json и npm-shrinkwrap.json, что осложеннно тем, что обычно при таком подходе они не используются, НО, если возник конфликт — все что до этого так берегли полетит в топку, и именно они будут определять что в итоге окажеться закоммичено с node_modules в репозитории?
самая очевидная фича, которой годами не было в npm — это lock-файл. Нет lock-файла — нет фиксирования версий.
Так в package.json ведь указываются версии зависимостей. Или я чего-то не так понимаю?
В npm существует возможность указывать не конкретную версию — а диапазон (т.н. "мягкие" зависимости). И если для своего проекта достаточно эту возможность не использовать — то что делать когда эта возможность используется сторонними пакетами?
То есть lock файл нужен, чтобы фиксировать версии всех зависимостей, а не только тех, которые присуствуют в проекте явно?
Да, всё так. Lock-файл (эта идея пришла, кажется, из Bundler'а и с огромным успехом сейчас используется в Rust'овом Cargo) фиксирует версии всех зависимостей, транзитивных в том числе. Кажется, ещё yarn решает проблему с недетерминированным порядком установки пакетов и их расположению в файловой системе, которая есть у npm.
Если соблюдается semver, то версии 2.X.X не содержат braking changes
а) помимо соблюдения семвера нужно, чтобы новые куски кода не ломали старый по недосмотру — это бывает, но в идеальном мире
б) >=2 — это все же и 3.* тоже
в) все-таки надежда на соблюдение сторонними разработчиками правил — это непозволительная роскошь для продакшна
Комментарии сообщества в духе "надо было в npm законтрибьютить" забавляют. В OSS никто никому ничего не должен, а конкуренция(форки, аналоги) в итоге, только улучшает конечный продукт для пользователя.
Но странно, что yarn выложили, а registry — нет.
Старый Добрый Монополист в стабильных условиях всегда лучше конкуренции. Вот, был один npm и было нормально (но не супер, ведь монополисты, они такие). По идее, монополию должна сменять конкуренция более технологичных продуктов в ситуации отсталости монополиста и/или динамичной смены условий на рынке.
И при этом почти всегда конкуренты новой формации видятся более слабыми и некрутыми. Может, yarn это будущее, а противники yarn превращаются в луддитов с каждым новым комментом.
![](https://habrastorage.org/files/c06/c0d/506/c06c0d5061e24945959056b787433a33.jpeg)
Одно дело, когда эти процессы идут годами-десятилетиями и совсем другое, когда каждые неск. месяцев нет-нет, да появится очередной «убийца php/npm/js».
Это дезориентирует( особенно начинающих).
Это приводит к дроблению сообщества и бесполезной трате его ресурсов на изобретение очередных велосипедов, абсолютное большинство из которых загнётся в грязи и тени.
И, что самое главное — это приводит к увеличению расхода времени программиста на что угодно, кроме, собсно, разработки( чтение бесконечной документации очередного пупер-инструмента, попытки выяснить, как он * работает итд итп).
Как итог, в большинстве своём, ничего кроме вреда, подобное не несёт.
В конкуренции, как и во многом остальном, д.б мера, а не нескончаемый поток почти идентичных по своей сути продуктов, цвета уже не столь небесного/радужного, сколь жёлтого или, того хуже, коричневого…
Никто не призывает новичка использовать yarn. NPM освоит и хорошо.
Тот факт, что каждый месяц что-то выходит — особенность области. Надо учиться различать перспективные новинки, от однодневок.
А что по вашему делать, если npm устанавливает зависимости 5 минут, а yarn — 30сек?
Мне кажется, что я слышал эти имена еще когда Руби и Рельсы были мейнстримом.
Складывается впечатление, что есть небольшое сообщество энтузиастов на зарплате, которое задает тон генеральной линии развития JS инфраструктуры. Как только им надоедает очередной фреймворк — они его забрасывают и начинают очень бурно создавать что-нибудь другое.
По-моему, когда в умах первая мысль «зачем еще один?», а не «вау! нужно перевести на новую технологию!» — это признак взросления.
Это всего лишь еще один инструмент — хотите используйте, хотите — нет.
Лично мне инициатива нравится, поскольку в при работе с npm иногда возникает великое большое множество проблем – низкая производительность, большой объём зависимостей на диске и т.д., и очевидно, что npm Inc часть этих проблем не решает, и если хотя бы некоторые из них будут качественно решены посредством yarn, это будет замечательно, а поддержка необходимых фичей вроде lifecycle scripts для более качественной совместимости с npm появится со временем, поскольку сообщество этого требует.
Если что, ни в кого ссаными тряпками кидаться не хотел, и всё написанное – лишь моё мнение, которое имеет право на жизнь так же, как и статья автора.
Нет у Yarn действительно важных фич, то чего действительно не хватает так это указания версии nodejs в package.json и соответственно работы приложения именно с этой версией вне зависимости от того что стоит непосредственно в окружении.
Как вы это себе представляете? Фиксация версии ноды — не задача пакетного менеджера.
На самом деле, это б-м реально.
Если загружать голые рантаймы ноды для каждого пользователя и производить запуск через прокси-executable. Пример — nvm, который просто скрипт.
Проблем тут две
- Рантайм для самого yarn
- Жёсткая обратная совместимость самого yarn.
Вы забыли третью проблему — что делать, если два разных пакета требуют разные версии рантайма?..
Для инструмента — да. Но что делать тому, кто эту радость будет запускать? :)
А представьте себе такую жизненную ситуацию, у вас есть сервер на котором работает жирный такой сервис на Nodejs, и ему года 3, и все эти годы никто в него не заглядывает а его разработчик давно уволился, и тут вам нужно задеплоить туда еще один сервис, естественно написанный на куда более свежей ноде, и вот проблема этот древний сервис не запускается на новой версии Nodejs. И решений сейчас тут только два и оба та еще "радость", это ковырять старый сервис решая проблемы совместимости или ковырять что-либо из контейнеризации типа Docker.
Как человек, который любит копаться в чужом коде, я все-таки попробую поправить старый код. Не настолько все плохо в ноде с обратной совместимостью чтобы можно было серьезно застрять на этой фазе.
Если старый код настолько плох что даже я в нем не смогу разобраться — можно же просто поставить две ноды на сервер… Но вашу проблему я понял. Так вот, через фиксацию версии ноды она не решается.
Потому что старый и новый код в любом случае придется запускать с разными рантаймами. А значит, они должны ставиться как дополнительные пакеты, а не быть атрибутом проекта.
Пакеты же с дополнительными рантаймами можно создать и в рамках текущей функциональности npm. Кажется, я даже видел посвященный этому проект.
Именно поэтому и я говорил что это не задача пакетного менеджера.
Мой опыт рефакторинга старого приложения под более свежую версию Nodejs был настолько неудачным, что у меня осталась психологическая травма. Возможно помните что ранняя версия express изначально хранила в себе большую часть модулей, а потом авторы решили вынести их по разным пакетам, и это была проблема только одного из множества пакетов изменивших API. Я отлично понимаю почему зафиксировать версию ноды для приложения проблематично при текущей архитектуре, но уверен что решение в рамках пакетного менеджера придумать возможно, пусть хоть он докер контейнеры разворачивает под капотом, хорошая практика оставить на усмотрение разработчика выбор — лишний оверхед или решать конфликты ручками.
Даже с докер-контейнерами не получится зафиксировать. Просто из-за постановки задачи. Вам нужны две разные ноды в одном проекте. А вы предлагаете оставить одно свойство для номера версии. Два разных значения в одно никак не залезут.
Просто представьте как вы будете записывать желаемое в файле package.json.
А то, что нужно вам, называется nvm
Да, действительно nvm exec 6.8.1 npm install & nvm exec appname
решают проблему. Это действительно круто, 2 года назад когда я столкнулся с проблемой подобное решение если и было то не гуглилось. Спасибо за наводку. А давайте представим что Yarn красиво интегрировал в себя nvm, и умеет читать из package.json
аттрибут "nodejs-version":"6.8.1". И теперь когда мы делаем yarn install
, yarn сам скачает нам нужную версию ноды и npm, а yarn run
будет у нас алиасом для nvm exec 6.8.1 appname
, для зависимых пакетов их локальный атрибут "nodejs-version" будет игнорироваться. И в итоге мы получаем 1. Более user friendly управление версией ноды для проекта 2. можно глобально обновлять ноду и не боятся что остальные сервисы перестанут работать. Вполне достойная как по мне фича, что бы сделать еще один менеджер пакетов (сарказм)
В чем проблема скомпилировать две версии node.js?
Я как пользователь пакетного менеджера не должен себе ничего представлять. У меня тут рядом есть пакетный менеджер из другой оперы — leiningen, там можно указать версию интерпретатора, и могу сказать что это очень удобно. Почему бы мне не хотеть того же от npm или Yarn?
Есть поле engines в package.json
для этого ("engines": { "node": ">4" }
) и флаг --engine-strict.
Все рушится