NPM — это пакетный менеджер. Он управляет зависимостями: наше приложение зависит от каких-то пакетов, а эти пакеты зависят от других пакетов и т. д. Изначально он создан для NodeJS, но сейчас там очень много всего и для фронтэнда.
- Скринкаст по NodeJS — обязательно видео с 1 по 9. Минимально-необходимые знания по NodeJS.
- What everybody should know about npm + слайды — обязательно.
- Документация NPM — понятная документация с видео-примерами.
- Рекомендуемые ссылки про NPM от технического директора NPM
NPM устанавливается вместе с NodeJS. Его так же можно поставить на Мак с помощью brew
или на Линукс с помощью apt
.
При установке глобальных пакетов на свежеустановленный NPM (например, npm install -g webpack
) могут вылетать EACCES-ошибки. Это связано с недостаточным уровнем доступа вашего пользователя к /usr/local
, куда NPM ставит глобальные пакеты.
Права доступа настраиваются парой команд из официального руководства. Вам нужен раздел Option 1.
❗ Не нужно устанавливать глобальные пакеты под sudo
.
👍 Вообще, стоит отдать предпочтение работе только с локальными пакетами. Так у всех на проекте будет одна и та же версия. См. ниже "Запуск бинарников локально".
NPM использует соглашение semver: MAJOR.MINOR.PATCH
.
При установке пакетов с флагом --save
или --save-dev
в package.json
по-умолчанию записывается его версия с кочергой: ^1.2.3
. Это значит, что при последующих установках NPM будет искать в репозитории пакеты не ниже версии 1.2.3
, но не выше 2.0.0
. То есть все патчи и минорные изменения.
Часто используется ~
. Тильда позволяет устанавливать только патчи. Например, ~1.2.3
даст установить все версии 1.2.x
до 1.3.0
.
Можно установить пакет, жестко прописав его версию: npm install PACKAGE --save --save-exact
. Тогда будет 1.2.3
и при последующих установках поиска обновлений не будет. Однако, наш пакет версии 1.2.3
имеет свой собственный package.json
. И там уже могут быть нечеткие зависимости и с ^
и с ~
.
Для того, чтобы NPM не искал обновления установленных пакетов (при релизе может быть не безопасно), применяют утилиту npm shrinkwrap
.
Устанавливаем библиотеку [email protected]
. В package.json
добавляется:
"dependencies": {
"jquery-ui": "^1.10.5"
}
^
говорит, что можно ставить минорные изменения (вторая цифра.)
Подключаем модуль для автокомплита:
require('jquery-ui/autocomplete.js');
Работаем над проектом 3 месяца, выпускаем в лайв. Далее идет поддержка.
Еще через 3 месяца на проект приходит новый разработчик, раскатывает проект и получает ошибку:
ERROR in ./src/city-autocomplete/js/index.js
Module not found: Error: Cannot resolve module 'jquery-ui/autocomplete.js' in ./src/city-autocomplete/js
@ ./src/city-autocomplete/js/index.js 4:4-40
При запуске npm install
скачалась версия 1.12.0
. Разработчики решили изменить в ней файловую структуру. Теперь нужно писать require('jquery-ui/ui/widgets/autocomplete.js')
.
Если бы на проекте был сгенерирован npm-shrinkwrap.json
, то установилась бы та версия пакета, с которой все работает и ошибки бы не было.
Если вдруг пропадет куда-то место на вашем SSD-диске, можно запустить npm cache clean
и удалить закешированные пакеты. Каждый новый пакет кешируется для последующей быстрой установки. Их может накопиться очень много.
В наших проектах часто используются следующие NPM-скрипты в package.json
:
npm run dev
— запуск окружения для локальной фронтэнд-разработки. Нет минификации, запускается отдельный сервер для обслуживания ресурсов, все работает максимально быстро.npm run prod
— сборка ресурсов для продадкшена (запускается на Дженкенсе) или локальной работы с собранными ресурсами, когда не нужно писать стили и JS (для бэкенд-разработки).
Скрипты, которые необходимо запускать в процессе работы с проектом, нужно упомянуть в README.md
.
Некоторые пакеты поставляются с утилитами, которые можно запускать из командной строки: gulp
, webpack
и пр. Симлинки на них NPM собирает в папке node_modules/.bin
.
Если такой NPM-пакет упоминается в разделе "scripts"
в package.json
, то NPM будет пытаться его запустить локально, из папки node_modules
, которая находится в проекте. А если он его там не найдет, то попытается найти глобально.
Так, если в package.json
есть, например, скрипт "dev": "webpack-dev-server --hot"
, то, когда мы пишем в консоли npm run dev
, запускается webpack-dev-server
из папки node_modules
, которая в проекте.
- Устанавливать пакеты из готового
package.json
. - Создавать новый
package.json
и сохранять в него зависимости при установке пакетов. - Понимать semver.
- Устанавливать определенную версию пакета.
- Разбираться во всех этих
^
и~
. - Находить устаревшие пакеты из
package.json
и обновлять их. - Чистить локальный кэш NPM.
- Знать, как залочить версии пакетов на проекте.
- Уметь работать с
npm run
-скриптами и скриптами по-умолчанию. - Уметь добавить пакет в
package.json
из удаленного репозитория (Гтихаб, Битбакет и пр.). - Понимать отличия между глобальными и локальными пакетами, уметь настроить npm-скрипты для работы только с локальными пакетами.