Что такое NPM: гайд по менеджеру пакетов для JavaScript
Разбираемся, как работает пакет с пакетами для JavaScript.


Иллюстрация: Катя Павловская для Skillbox Media
Если вы начали разрабатывать проект на Node.js, то уже наверняка заметили, что работа с библиотеками может быть сложной и выматывающей. Постоянно надо следить за тем, чтобы модули проекта не терялись, вовремя обновлялись и не конфликтовали с другими пакетами. В этой статье рассказываем про NPM — пакетный менеджер, который упрощает работу со сторонними библиотеками в JavaScript.

ЭКСПЕРТ
Владимир Вавщик
Эксперт по фронтенд-разработке в Skillbox, фрилансер.
Содержание
Знакомство с NPM
NPM (Node Package Manager) — менеджер пакетов для программной платформы Node.js. С его помощью можно устанавливать библиотеки, управлять зависимостями и редактировать метаданные проекта.
Перед началом работы с NPM надо скачать и установить пакет Node.js с официального сайта проекта. После этого нужно запустить любой интерфейс командной строки — приложение для ввода команд. Это может быть PowerShell, терминал, консоль или командная строка. Всё зависит от вашей операционной системы.

Читайте также:
Загрузка и установка пакетов
Пакет — упакованный код, который может быть библиотекой, утилитой или полноценным приложением. Разработчики используют общедоступные пакеты, чтобы не изобретать велосипед — то есть не писать с нуля модули, которые уже давно созданы. Представьте, что вы пишете бота, который конвертирует валюты. Можно самостоятельно продумать логику модуля, который будет сверять курс, например, с сайтом Центрального банка, а можно воспользоваться уже готовым пакетом и сэкономить время.

Скриншот: NPM / Skillbox Media
В экосистеме Node.js пакеты устанавливаются с помощью менеджера NPM, а хранятся они в публичных репозиториях. Это значит, что любой желающий может изучить их код и принять участие в разработке. Список доступных пакетов по ключевым словам доступен на сайте NPM.

Читайте также:
Для установки в NPM используется команда install, после которой надо указать название пакета:
npm install имя_пакета
Можно использовать краткую форму команды:
npm i имя_пакета
Если нужно установить несколько модулей, то можно сразу указать их названия:
npm install имя_пакета имя_пакета2 имя_пакета3...
Например, вот так можно установить Lodash — популярную у JS-разработчиков библиотеку для работы с массивами, строками и другими типами данных:
npm install lodash

Скриншот: командная строка Windows / Skillbox Media
Важно
Во время установки следите за названиями модулей, которые вы вводите в терминале, чтобы не стать жертвой тайпсквоттинга — хакерской атаки, эксплуатирующей ошибки ввода.
Представим, что в репозитории есть полезный модуль под названием express. Злоумышленники создают заражённый пакет с максимально похожим названием (например, expres) в надежде, что пользователь ошибётся во время ввода команды, не перепроверит данные и установит вирус. С помощью тайпсквоттинга злоумышленники часто распространяют ПО, которое ворует данные разработчиков, включая пароли от различных сервисов.
Установка зависимостей
Зависимости — набор пакетов, которые нужны для работы приложения. Они устанавливаются командой npm install и записываются в файл package.json в разделе dependencies.
Файл package.json можно отредактировать вручную, чтобы автоматически установить все необходимые пакеты. Сперва надо создать сам проект. Для этого с помощью команды cd перейдём к директории, в которой будет храниться папка проекта. В нашем случае это «Рабочий стол»:
cd C:/Users/User/Desktop
После этого выполним команду npm init, которая инициализирует новый проект и создаст файл package.json:
npm init

Скриншот: командная строка Windows / Skillbox Media
Во время создания проекта NPM спросит его название, автора и версию. Важно помнить, что название должно быть в нижнем регистре, а неактуальные пункты можно пропустить. Если не хочется вводить все данные, то можно воспользоваться командой npm init -y, которая автоматически сгенерирует шаблон. В итоге в папке появится файл package.json с вот таким содержимым:
{
"name": "test",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Me",
"license": "MIT",
"description": ""
}
Теперь в раздел dependencies можно добавить названия пакетов с указанием версий в формате "название_пакета": "версия":
{
"name": "test",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Me",
"license": "MIT",
"description": "",
"dependencies": {
"express": "4.17.1",
"lodash": "4.17.21",
"gm": "1.22.0"
}
}
Сохраняем файл и выполняем команду:
npm install

Скриншот: командная строка Windows / Skillbox Media
Менеджер NPM проверит список зависимостей, создаст файл package_lock.json и папку node_modules, в которой будут храниться скачанные модули проекта.
Автоматическое добавление зависимостей
В NPM предусмотрена возможность автоматического добавления зависимостей в файл package.json, чтобы не приходилось самостоятельно редактировать раздел dependencies. Для этого используют следующие флаги команд:
- --save или -S — флаг, который во время установки добавляет название пакета и его версию в раздел dependencies. Важно отметить, что этот флаг нужен только в старых версиях NPM. Начиная с NPM 5 все устанавливаемые пакеты автоматически добавляются в раздел dependencies.
npm install music-metadata --save

Скриншот: командная строка Windows / Skillbox Media
- --save-dev или -D — флаг, который во время установки добавляет зависимость в раздел devDependencies. Он нужен для перечисления пакетов, которые используются только для разработки и не нужны в финальной версии проекта. Например, это могут быть фреймворки для тестирования, линтеры или инструменты сборки.
npm install music-metadata --save-dev
Обновление пакетов
Для обновления модулей используется команда npm update. Она указывает менеджеру пакетов, что надо проверить список зависимостей в package.json и установить все доступные обновления, если нет ограничения.
Ограничения указываются в разделе dependencies с помощью символа каретки (^). Например, список зависимостей с ограничениями будет выглядеть так:
{
"name": "test",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Me",
"license": "MIT",
"description": "",
"dependencies": {
"express": "^4.17.1",
"lodash": "^4.17.21",
"gm": "^1.22.0"
}
}
Это значит, что NPM сможет обновить модули только до минорных версий и патчей, не трогая мажорные версии.
?️ Технические детали
Пакеты в NPM используют принцип семантического версионирования, когда версии записываются в формате MAJOR.MINOR.PATCH, где:
- MAJOR (мажорная версия) — масштабные изменения, которые могут повлиять на совместимость модуля с другими пакетами и инструментами.
- MINOR (минорная версия) — интеграция новых функций, которые не мешают продолжать использовать пакет в проекте.
- PATCH (патч) — исправления ошибок, которые никак не влияют на функции и возможности модуля.
Если надо обновить конкретный пакет, то можно использовать команду update с указанием имени пакета:
npm update имя_пакета
Загрузка пакетов определённых версий
Если вы автоматически обновили все пакеты в проекте, а потом заметили, что в одном из них появились баги или пропали нужные функции, то в NPM можно откатиться до предыдущей версии и запретить установку обновлений.
Для начала надо узнать, какая версия шла перед злосчастным обновлением. Например, сейчас установлен пакет music-metadata 10.2.0. Список всех версий можно посмотреть в калькуляторе NPM SemVer: вводим название модуля и диапазон версий. В нашем случае это 10.x.x — все релизы мажорной версии под номером 10. Также список версий доступен на странице пакета в NPM.

Скриншот: NPM SemVer / Skillbox Media
Мы видим, что до 10.2.0 была версия 10.1.0, с которой у нас не возникало проблем. Открываем файл package.json и меняем номер версии music-metadata:
{
"name": "test",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Me",
"license": "MIT",
"description": "",
"dependencies": {
"express": "^4.17.1",
"gm": "^1.22.0",
"lodash": "^4.17.21",
"music-metadata": "10.1.0"
}
}
После этого выполняем команду npm install.

Читайте также:
Запуск скриптов
В файле package.json можно указать скрипты и сложные команды, которые должны запускаться для сборки проекта или вывода ошибок. Например, разработчики используют Webpack для сборки нескольких файлов с JS-кодом в одно приложение. Для запуска сборки надо выполнить следующую команду:
NODE_ENV=production webpack -p --config webpack.conf.js

Читайте также:
Эту задачу можно упростить, добавив команду в разделе scripts файла package.json. Перед командой надо добавить название скрипта, с помощью которого можно будет запустить его выполнение. В нашем случае это prod:
{
"name": "test",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"prod": "NODE_ENV=production webpack -p --config webpack.conf.js"
},
"author": "Me",
"license": "MIT",
"description": "",
"dependencies": {
"express": "^4.17.1",
"gm": "^1.22.0",
"lodash": "^4.17.21",
"music-metadata": "10.1.0"
}
}
После этого длинную и сложную команду можно запускать с помощью более лаконичной npm run prod.
Теперь напишем собственный скрипт, который будет выводить в терминал фразу Hello, Developer!. Для этого в раздел scripts добавим строку "say-hello": "echo 'Hello, Developer!'":
{
"name": "test",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"say-hello": "echo 'Hello Developer!'"
},
"author": "Me",
"license": "MIT",
"description": "",
"dependencies": {
"express": "^4.17.1",
"gm": "^1.22.0",
"lodash": "^4.17.21",
"music-metadata": "10.1.0"
}
}
Теперь выполним в терминале команду npm run say-hello и увидим результат — сообщение, которое указали в файле package.json:

Скриншот: командная строка Windows / Skillbox Media
Файл package.json
Файл package.json — важнейший элемент проектов в экосистеме Node.js. Мы уже рассмотрели, как можно использовать файл для установки зависимостей, а теперь разберёмся со структурой и другими полезными возможностями.
Структура файла
Содержимое файла package.json записывается в формате JSON, поэтому важно соблюдать требования к его оформлению. Если их проигнорировать, то NPM не сможет прочитать содержимое. Сам файл содержит метаданные проекта, которые задаются с помощью соответствующих разделов:
- version — текущая версия программы, которая задаётся по правилам семантического версионирования.
"version": "1.0.0"
- description — краткое описание программы и её возможностей.
"description": "This utility works only with numbers"
- main — указывает на файл, который будет точкой входа в приложение.
"main": "files/first.js"
- private — отвечает за возможность публикации приложения в NPM. Модификатор true запрещает публиковать приложение.
"private": true
- scripts — задаёт список скриптов, которые можно запустить.
"scripts": {
"say-hello": "echo 'Hello Developer!'"
}
- dependencies — список зависимостей, без которых приложение не будет работать.
"dependencies": {
"express": "^4.17.1",
"gm": "^1.22.0",
"lodash": "^4.17.21",
"music-metadata": "10.1.0"
}
- devDependencies — список зависимостей, которые нужны только во время разработки.
"devDependencies": {
"autoprefixer": "^7.1.2",
"babel-core": "^6.22.1"
}
- engines — список версий Node.js, на которых приложение будет работать.
"engines": {
"node": ">= 5.0.0",
"npm": ">= 2.5.0",
"yarn": "^0.14.0"
}
- browserslist — список браузеров и их версий, в которых приложение будет работать.
"browserslist": {
"last versions",
"not ie <= 10"
}
- license — содержит информацию о лицензии, под которой публикуется код.
"license": "MIT"
- author — информация об авторе проекта: имя, сайт, электронная почта и другие данные.
{
"author": {
"name": "Vasily Popov",
"email": "v.popov@siteexample.ru",
"url": "https://v-popov.ru"
}
}
- contributors — список людей, которые внесли вклад в развитие проекта.
{
"contributors": [
{
"name": "Vasily Popov",
"email": "v.popov@siteexample.ru",
"url": "https://v-popov.ru"
}
]
}
- bugs — ссылка на баг-трекер проекта.
{
"bugs": "https://github.com/v_popov/package/issues"
}
- homepage — ссылка на официальный сайт проекта.
{
"homepage": "https://v-popov.ru"
}

Читайте также:
Версионирование
Во время работы над проектом чаще всего изменяется содержимое разделов dependencies и devDependencies. Разработчики интегрируют новые пакеты и меняют версии уже имеющихся. Для всего этого используется принцип семантического версионирования, а в NPM есть инструменты для удобного упрвления версиями пакетов. С несколькими из них мы уже сталкивались в этой статье, а сейчас посмотрим на всю коллекцию специальных символов.
Для управления версиями пакетов NPM используются следующие символы:
Символ | Значение | Пример |
---|---|---|
~ | Можно устанавливать только патчи пакета (1.2.x) | ~1.2.0 |
^ | Можно устанавливать только минорные версии и патчи (1.x.x) | ^1.2.0 |
* | Последняя версия модуля | * |
> | Выше указанной версии | >1.2.0 |
< | Ниже указанной версии | <1.2.0 |
= | Строго указанная версия модуля | =1.2.0 |
>= | Версия, равная указанной или выше | >=1.2.0 |
<= | Версия, равная указанной или ниже | <=1.2.0 |
- | Диапазон версий | 1.2.0-1.3.4 |
latest | Последняя версия модуля | latest |
|| | Логическое ИЛИ | <1.2.1 || >1.3.4 |
Файл package-lock.json
Файл package-lock.json создаётся автоматически при установке NPM-пакетов. Если вы следовали инструкциям выше, то наверняка заметили, что этот файл уже появился в папке проекта. Он нужен для того, чтобы зафиксировать зависимости, которые нужны для работы сторонних пакетов.
Например, программист решил разработать библиотеку для обработки онлайн-платежей. Он решил использовать несколько готовых модулей из NPM и на их основе написал собственное решение.
Спустя какое-то время мы нашли эту библиотеку и решили добавить в свой проект. Информация о ней зафиксируется в уже знакомом нам файле package.json, а зависимости, без которых не будет работать сторонняя библиотека, запишутся в дополнительный файл package-lock.json. Если говорить проще, то в файле package-lock.json описаны зависимости зависимостей.
Если заглянуть в папку node_modules, то там можно найти пакеты, которые вы скачали сами, и случайные модули. Они установились автоматически, потому что нужны для работы библиотек, которые вы используете. Возможным это стало благодаря записям в package-lock.json.

Скриншот: «Проводник» Windows / Skillbox Media
Что запомнить
- NPM — удобный менеджер пакетов для тех, кто пишет код на JavaScript.
- С помощью NPM можно устанавливать библиотеки и модули, которые расширяют возможности языка программирования.
- Встроенные инструменты управления зависимостями позволяют быстро настраивать окружение проекта и запускать его на сервере или другом компьютере.
- В NPM предусмотрены удобные функции для автоматического обновления зависимостей до указанных версий.
Больше интересного про код — в нашем телеграм-канале. Подписывайтесь!