[Из песочницы] npm@3: будущее уже здесь
В конце июня была выпущена первая бета третьей версии npm. А 26-го сентября версия 3.3.3 была помечена как latest в официальном репозитории, что знаменует окончание бета тестирования и доступность третьей версии для всех разработчиков. Но переход на третью версию не очень быстрый. К примеру, скачав node.js с официального сайта мы получим в комплекте версию 2.x npm. В данный момент разработчики параллельно поддерживают две версии, 2.x и 3.x — почти как у Python. Надеюсь, с npm переход получится быстрее, разработчики грозятся приурочить его к выходу Node 5. Ну а пока они этого не сделалия, предлагаю вам ознакомиться с нововведениями и узнать как можно одной командой обновить себе npm на тройку.
Одноуровневая структура node_modules
Одной из проблем npm была древовидная организация зависимостей внутри node_modules. На windows это порождало слишком длинные пути к файлам и большая часть программ теряла возможность работать с такими файлами. Плюс дублирование зависимостей: если популярная библиотека использовалась несколькими другими библиотеками, то каждая получала свою копию в своей личной node_modules. Частично это можно было исправить утилитой dedupe, но в ряде случаев npm install обрывался с ошибкой намного раньше, просто потому что на виртуалке заканчивались файловые дескрипторы.
В третьей версии npm большинство зависимостей устанавливается в одну, корневую директорию node_modules. Исключения составят разные версии библиотек: если в процессе изучения зависимостей npm обнаружит, что нужно установить несколько разных версий одной библиотеки, то одна из них будет установлена в корневую директорию node_modules, а остальные — в локальные node_modules.
peerDependencies больше не ставятся автоматически
Среди всех способов указать зависимости, peerDependencies всегда стояло особняком. С помощью этого поля можно было указать “обратную зависимость” для плагинов: с какими версиями библиотеки или утилиты плагин совместим. В случае, если два плагина требовали несовместимой версии библиотки, то npm сообщала об ошибке и прекращал установку. Но был один неприятный момент: если на момент установки плагина библиотека еще не была установлена, то npm автоматически ее устанавливал. Более того, не в директорию node_modules плагина, а на уровень выше. В целом логично, но приводило к неприятным последствиям с неправильными версиями установленных зависимостей. В 3-й версии автоматическую установку убрали и ограничились предупреждающим сообщением. Теперь за наличием библиотеки в списке зависимостей должен следить тот, кто указал в этом списке плагин.
Multi-stage installer
В предыдущей версии скрипты, указанные в таких полях scripts как preinstall и postinstall выполнялись во время установки зависимости. При этом не было гарантии что при выполнении ‘postinstall’ все дочерние зависимости уже будут установлены. Что приводило к большому количеству проблем. В третьей версии установка разделена на шаги:
- npm скачивает все зависимости
- выполняется скрипт ‘preinstall’ для всех зависимостей
- npm устанавливает скачанные зависимости в директорию node_modules (и поддиректории, в случае конфликтов версий).
- выполняется скрипт ‘postinstall’ для всех установленных зависимостей.
Это изменение позволило избавиться от большого количества “долгоиграющих” проблем и сделало выполнение скриптов во время инсталляции простым и понятным. Надеюсь.
Мелочи, в ассортименте
Кроме трех крупных изменений, в третьей версии npm есть множество мелких. Это и новое отображение прогресса инсталляции с progress bar, и ключи командной строки --only=/--also=, сделавшие --dev deprecated и много чего по мелочи. Очень рекомендую почитать историю изменение в разделе releases. Там совершенно чумовая девочка community manager которая описывает изменение не просто с огоньком — она жжет напалмом по площадям. Посмотрите, вам понравится.
Чтобы установить последнюю версию npm, достаточно выполнить следующее заклинание командной строки:
npm install -g npm@3
Под OSX могут быть проблемы, если npm было установлено с помощью homebrew. Для такой конфигурации заклинание немного иное:
cd /usr/local/lib/node_modules/npm
npm install -g npm@3