Перейти к основному содержимому

npm — команды, зависимости и lock-файлы

Разработчику

npm — менеджер пакетов Node.js

Менеджер пакетов — это программное обеспечение, которое автоматизирует процесс установки, обновления, настройки и удаления внешних библиотек и инструментов, необходимых для разработки программного обеспечения, абстрагируя разработчика от ручного поиска, загрузки и подключения зависимостей. Менеджер пакетов решает целый комплекс задач: он предоставляет централизованный реестр, где хранятся все доступные пакеты с их версиями и метаданными, обеспечивает разрешение зависимостей, автоматически вычисляя и загружая все подзависимости, необходимые для работы устанавливаемого пакета, и управляет конфликтами версий, когда разные пакеты требуют разные версии одной и той же библиотеки. Кроме того, менеджер пакетов обеспечивает воспроизводимость сборок, позволяя зафиксировать точные версии всех зависимостей в специальном файле блокировки, что гарантирует, что все разработчики в команде и продакшен-серверы получат абсолютно одинаковое окружение, исключая ошибки, связанные с различиями в версиях. Менеджер также предоставляет механизмы для разделения зависимостей на производственные и зависимости для разработки, такие как линтеры, тестовые фреймворки и инструменты сборки, которые не нужны в эксплуатационном окружении, что позволяет сократить объем устанавливаемого кода на боевых серверах. В современной веб-разработке менеджеры пакетов стали неотъемлемой частью экосистемы, и кроме npm существуют альтернативные решения, такие как yarn и pnpm, каждое из которых предлагает свой подход к управлению зависимостями, отличаясь скоростью работы, организацией хранения пакетов на диске и стратегиями разрешения конфликтов. Без менеджера пакетов разработка сложных проектов была бы практически невозможна, поскольку ручное управление сотнями или тысячами сторонних библиотек привело бы к огромным затратам времени и неизбежным ошибкам.

Пакет — это минимальная единица распространения программного кода в экосистеме Node.js и других платформах, представляющая собой архив с файлами, который содержит исполняемый код, метаданные о себе в виде файла package.json и может включать документацию, тесты, скомпилированные бинарные файлы и другие ресурсы, необходимые для работы библиотеки или инструмента. Каждый пакет имеет уникальное имя в реестре npm и строгую версию, которая соответствует правилам семантического версионирования, что позволяет разработчикам точно указывать, какую именно версию пакета они хотят использовать в своем проекте, а также понимать, какие изменения вносит каждое обновление. Пакет может быть как простой утилитой, выполняющей одну небольшую задачу, например, форматирование дат, так и огромным фреймворком, предоставляющим сотни API для построения веб-приложений, таких как Express или React, причем экосистема npm построена на принципе максимального переиспользования кода, поэтому даже самые крупные проекты собираются из сотен мелких пакетов. Пакеты могут быть публичными, доступными для скачивания любым разработчиком, или приватными, ограниченными для использования внутри одной организации или команды, что часто используется в корпоративной разработке для защиты интеллектуальной собственности. Жизненный цикл пакета включает его создание, опубликование в реестре, обновление с новыми версиями и, в некоторых случаях, деприкацию, когда пакет помечается как устаревший с рекомендацией перейти на альтернативное решение. Важно понимать, что пакет в npm не тождественен модулю в коде: один пакет может содержать множество модулей и экспортировать различные части своей функциональности через точку входа, указанную в поле main файла package.json, или через субпакеты, доступные по подпутям.

npm — это аббревиатура от Node Package Manager, официальный и наиболее распространенный менеджер пакетов для экосистемы Node.js, который поставляется вместе с установщиком Node.js и предоставляет разработчикам мощный инструмент командной строки для управления зависимостями проектов, публикации собственных библиотек и взаимодействия с крупнейшим в мире репозиторием программного обеспечения, содержащим более двух миллионов пакетов. npm выполняет широкий спектр задач: он позволяет устанавливать сторонние библиотеки и инструменты из удаленного реестра, управлять версиями этих зависимостей, обновлять их до новых версий, удалять ненужные пакеты, а также публиковать собственные модули для использования другими разработчиками по всему миру. Ядром работы npm является файл package.json, который служит манифестом проекта, описывающим все метаданные, включая название проекта, версию, автора, лицензию, а главное — список всех зависимостей, необходимых для работы приложения как в среде разработки, так и в продакшене. npm обеспечивает семантическое версионирование, позволяя указывать диапазоны допустимых версий для каждого пакета, что дает возможность автоматически получать обновления с исправлениями ошибок, но при этом избегать критических изменений, ломающих приложение. Кроме того, npm включает в себя инструменты для проверки безопасности зависимостей через команду npm audit, которая сканирует дерево пакетов на наличие известных уязвимостей и предлагает способы их устранения. Менеджер пакетов создает папку node_modules в корне проекта, где хранит все загруженные пакеты, формируя сложную иерархическую структуру, которая может быть оптимизирована с помощью механизма дедупликации для минимизации занимаемого места и ускорения загрузки модулей. Вся экосистема Node.js построена вокруг npm, и практически любой проект, независимо от его размера, использует этот менеджер для подключения внешнего кода, что делает его незаменимым инструментом в арсенале каждого разработчика на JavaScript.

npm (Node Package Manager) идёт вместе с Node.js и отвечает за три вещи: установку библиотек, запуск скриптов проекта и публикацию пакетов в реестр npmjs.com. Без уверенной работы с npm сложно подключить Express, тесты или TypeScript — вы будете копировать команды из README, не понимая, что они делают.

Теория runtime и event loop — в Node.js — серверный JavaScript. Структура папок и package.json поля — в Структура Node-проекта. Шпаргалка команд — в Справочник по Node.

Маршрут по блоку Node.js

ШагСтатья
1Первая программаnpm init, npm run
2Node.js — основы
3Вы здесь — npm углублённо
4Структура проекта
5Express

Проверка npm

node -v
npm -v

Разбор:

  • npm ставится вместе с Node.js с nodejs.org (LTS).
  • Версия npm влияет на формат lock-файла и поведение npm audit.
  • На Linux не используйте устаревший apt install nodejs без официального репозитория — часто нет актуального npm.

Проверка npm — это базовая диагностическая процедура, выполняемая после установки Node.js и npm, целью которой является убедиться в корректной установке менеджера пакетов, его доступности в командной строке и правильной настройке системных переменных окружения для бесперебойной работы. Проверка обычно начинается с выполнения команды npm -v в терминале, которая выводит номер установленной версии npm, и если команда выполняется успешно, это означает, что npm установлен и его исполняемый файл находится в пути, доступном для командной оболочки. Аналогично, команда node -v проверяет установку самого Node.js, поскольку npm тесно связан с ним и требует наличия определенной версии движка для корректной работы всех функций. Более глубокая проверка включает выполнение команды npm config list для просмотра текущих настроек менеджера, таких как реестр по умолчанию, прокси-серверы, пути к кешу и другим важным параметрам, а также проверку прав доступа к глобальной директории установки, поскольку недостаток прав может привести к ошибкам при установке глобальных пакетов. В некоторых случаях разработчики выполняют пробную установку небольшого пакета, например, npm install lodash --no-save, просто чтобы убедиться, что сетевое соединение с реестром работает, а сам процесс скачивания и распаковки не вызывает ошибок. Проверка также может включать анализ версии npm на предмет совместимости с установленной версией Node.js, так как слишком старый менеджер может не поддерживать современные функции реестра или форматы пакетов, а слишком новый — использовать синтаксис, который не понимает более старая версия Node.js. Эта простая, но критически важная процедура часто является первым шагом в любом руководстве по настройке окружения и позволяет избежать множества проблем в самом начале работы над проектом.


Инициализация проекта

mkdir my-api && cd my-api
npm init
npm init -y

Разбор:

  • npm init задаёт вопросы интерактивно (имя, версия, лицензия).
  • npm init -y создаёт package.json с дефолтами — удобно для учебных проектов.
  • Файл package.jsonманифест — имя пакета, скрипты, зависимости. Подробнее о полях — Структура Node-проекта и правила разработки.

Инициализация проекта — это процесс создания базовой структуры и метаданных для нового программного проекта с помощью менеджера пакетов, который обычно выполняется командой npm init в корневой директории проекта и приводит к формированию файла package.json, содержащего всю необходимую информацию о проекте. При выполнении инициализации менеджер задает разработчику серию интерактивных вопросов, касающихся названия проекта, версии, описания, точки входа, автора, лицензии и других метаданных, после чего генерирует файл package.json с этими значениями, хотя существует также возможность быстро создать файл со значениями по умолчанию с помощью флага -y. Инициализация является обязательным шагом для любого проекта, который будет использовать сторонние зависимости или планирует быть опубликованным в реестре npm, поскольку package.json служит центральным манифестом, содержащим не только метаданные, но и списки зависимостей, скрипты для автоматизации задач и различные конфигурации для инструментов разработки. После инициализации разработчик может приступить к установке необходимых пакетов, которые автоматически будут записываться в разделы dependencies или devDependencies файла package.json, что обеспечивает прозрачность и воспроизводимость окружения проекта. Процесс инициализации также создает определенный контекст для всего проекта, задавая его имя и версию, что важно не только для внутренней организации, но и для взаимодействия с другими инструментами, которые читают этот файл для определения идентификатора проекта в различных системах непрерывной интеграции и развертывания. В современных практиках инициализация может быть расширена с помощью специальных инициализаторов, таких как npm init @scope/name, которые запускают шаблоны и генераторы для быстрого создания типовых проектов с предустановленными конфигурациями, что особенно удобно при создании множества однотипных микросервисов или библиотек.

Минимальный пример после npm init -y:

{
"name": "my-api",
"version": "1.0.0",
"type": "module",
"scripts": {
"start": "node src/index.js"
}
}

Поле "type": "module" включает ESM (import / export) в .js-файлах. Без него Node по умолчанию ожидает CommonJS (require).


Установка зависимостей

Установка зависимостей — это процесс загрузки и размещения в проекте всех необходимых внешних пакетов, указанных в файле package.json, вместе со всеми их подзависимостями, что выполняется командой npm install или npm i и является одной из самых частых операций в жизни любого Node.js-проекта. При выполнении установки npm анализирует дерево зависимостей, сверяет запрошенные версии пакетов с правилами семантического версионирования, вычисляет оптимальную структуру размещения пакетов в папке node_modules и загружает их из удаленного реестра, если они отсутствуют в локальном кеше. Установка может производиться в двух основных режимах: обычная установка для продакшена, которая загружает только те пакеты, что перечислены в разделе dependencies, либо установка с флагом --production, которая исключает пакеты из раздела devDependencies, что критически важно для экономии места и ускорения запуска на боевых серверах. При установке конкретного пакета с его последующим добавлением в зависимости используется флаг --save для добавления в dependencies или --save-dev для devDependencies, хотя в современных версиях npm установка без флагов по умолчанию добавляет пакет в dependencies, а явное указание --save-dev или --save-prod позволяет контролировать, куда именно записывается зависимость. Менеджер также генерирует или обновляет файл package-lock.json, который фиксирует точные версии всех установленных пакетов и их подзависимостей, что гарантирует, что при последующих установках на других машинах или в других окружениях будут получены абсолютно идентичные наборы зависимостей, исключая проблему "на моей машине работает". Установка зависимостей может быть ресурсоемкой операцией, особенно для проектов с большим количеством пакетов, поэтому современные менеджеры используют различные оптимизации, такие как параллельная загрузка, сжатие данных, использование глобального кеша и механизмы дедупликации для минимизации времени установки и объема занимаемой дисковой памяти.

КомандаДействие
npm installВсё из package.json по lock-файлу
npm install expressПакет в dependencies
npm install -D jestПакет в devDependencies (--save-dev)
npm install -g typescriptГлобально (редко нужно в проектах)
npm uninstall expressУдалить из манифеста и node_modules
npm ciЧистая установка только по lock (CI/CD)

Разбор:

  • dependencies — нужны при запуске приложения (Express, pg).
  • devDependencies — только для разработки (eslint, vitest, nodemon).
  • npm ci удаляет node_modules и ставит версии строго из package-lock.json — используйте в пайплайнах, не npm install.

После установки пакеты лежат в node_modules/. Папку не коммитят — восстанавливают командой npm install или npm ci.

Как npm раскладывает пакеты

Дерево пакетов — это сложная иерархическая структура всех зависимостей проекта, включающая как прямые зависимости, которые разработчик явно указал в package.json, так и транзитивные, то есть зависимости этих зависимостей, образующие в совокупности многоуровневое дерево, отражающее полный граф связей между всеми используемыми в проекте пакетами. Каждый пакет в этом дереве имеет свой собственный список зависимостей, которые, в свою очередь, могут зависеть от других пакетов, и так далее, создавая древовидную структуру, глубина которой может достигать десятков уровней, особенно в крупных проектах с сотнями или тысячами установленных пакетов. Менеджер пакетов строит это дерево таким образом, чтобы удовлетворить все требования к версиям, указанные каждым пакетом, при этом разрешая возможные конфликты, когда разные пакеты требуют разные версии одной и той же библиотеки, путем выбора наиболее подходящей версии и, при необходимости, установки нескольких разных версий одного пакета в разных частях дерева. В старых версиях npm дерево строилось вложенным образом, когда каждый пакет размещался в своей собственной папке node_modules внутри папки другого пакета, что могло приводить к огромной глубине вложенности и проблемам с длиной путей в операционных системах Windows, но современные менеджеры, включая npm начиная с версии 3, используют более плоскую структуру, размещая все пакеты на верхнем уровне, насколько это возможно, с помощью алгоритма дедупликации. Просмотреть дерево пакетов можно с помощью команды npm ls, которая выводит его в читаемом виде, показывая все установленные пакеты, их версии и взаимосвязи, что полезно для отладки проблем с версиями, поиска дублирующихся пакетов или анализа того, почему установлен тот или иной конкретный пакет. Понимание структуры дерева пакетов критически важно для управления зависимостями, поскольку неоптимальное дерево может увеличить размер приложения, замедлить загрузку модулей, вызвать конфликты версий и даже привести к трудноуловимым ошибкам во время выполнения из-за несовместимости между разными версиями одной и той же библиотеки, установленными в разных частях дерева.

С версии npm 3+ дерево плоское: общие зависимости поднимаются в корневой node_modules. При конфликте версий npm может создать вложенный node_modules внутри пакета-"виновника".

my-api/
├── node_modules/
│ ├── express/
│ ├── debug/ ← общая транзитивная зависимость
│ └── .bin/ ← CLI: nodemon, tsc, …
├── package.json
└── package-lock.json

require('express') или import … from 'express' ищут модуль в node_modules, поднимаясь от текущего файла к корню проекта.


Версии: SemVer и символы в package.json

SemVer — это сокращение от Semantic Versioning, что в переводе означает семантическое версионирование, представляющее собой формальную спецификацию и универсальный стандарт для обозначения номеров версий программного обеспечения, который использует трехкомпонентный формат MAJOR.MINOR.PATCH, где каждый компонент имеет строго определенное значение и семантику изменений, вносимых в пакет. Согласно правилам SemVer, увеличение номера PATCH происходит при внесении обратно совместимых исправлений ошибок, которые не изменяют общедоступный API и не влияют на поведение программы с точки зрения внешних потребителей, увеличение MINOR происходит при добавлении новой функциональности, которая также является обратно совместимой и не ломает существующий код, а увеличение MAJOR происходит при внесении изменений, которые нарушают обратную совместимость и требуют от разработчиков, использующих этот пакет, внесения изменений в их собственный код для продолжения работы. Семантическое версионирование также допускает использование дополнительных меток для предварительных версий, таких как alpha, beta или rc, которые добавляются через дефис после номера версии, например, 2.0.0-beta.1, указывая, что версия еще не готова для продакшена и находится в стадии тестирования. В экосистеме npm правила SemVer широко используются для указания диапазонов допустимых версий в файле package.json, где специальные символы, такие как карет и тильда, позволяют разработчикам точно контролировать, какие обновления они готовы принимать: исправления ошибок, минорные улучшения или только строго фиксированные версии. SemVer является критически важным для управления зависимостями, поскольку он предоставляет разработчикам предсказуемый способ понимания того, что изменится при обновлении пакета, и позволяет им принимать обоснованные решения о том, когда и как обновлять зависимости, минимизируя риск внесения непреднамеренных изменений в работающее приложение.

Символы в package.json — это специальные зарезервированные знаки, используемые в полях зависимостей файла package.json для указания правил обновления версий пакетов, которые определяют, какие именно версии менеджер пакетов будет устанавливать при выполнении команды npm install, и как он будет обрабатывать обновления при команде npm update. Наиболее распространенными символами являются карет, который обозначает разрешение на установку любой версии, совместимой с указанной, то есть без изменения мажорной версии, позволяя обновляться до самой свежей минорной или патч-версии, например, запись означает, что будут установлены версии от 2.0.0 до 3.0.0, но не включая 3.0.0. Тильда используется для более консервативного подхода, разрешая только патч-обновления без изменения ни мажорной, ни минорной версии, например, запись означает версии от 2.1.0 до 2.2.0, но не включая 2.2.0. Также используется символ звездочка для указания любой версии пакета, что крайне не рекомендуется из-за высокой вероятности внезапных ломающих изменений, и операторы сравнения, такие как больше или равно, меньше, больше, меньше или равно, а также точное указание версии без каких-либо символов, что закрепляет пакет на строго определенной версии и предотвращает любые автоматические обновления. Помимо символов для версионирования, в package.json используются другие символы в различных контекстах: например, символ слэша используется для указания путей к исполняемым файлам в скриптах, символ двоеточия используется для именованных скриптов и в некоторых конфигурационных полях, а символы фигурных скобок и квадратных скобок используются для обозначения объектов и массивов в самом формате JSON. Понимание всех этих символов и их значения является необходимым для корректной настройки проекта, поскольку неправильно указанные символы могут привести к установке неожиданных версий пакетов, что, в свою очередь, может вызвать ошибки в работе приложения, конфликты с другими зависимостями или даже полную неработоспособность продукта.

Формат SemVer: MAJOR.MINOR.PATCH (например 4.19.2).

Запись в package.jsonДиапазон
1.2.3Точная версия
~1.2.3Патчи: >=1.2.3 <1.3.0
^1.2.3Минор + патч: >=1.2.3 <2.0.0
*Любая (не используйте в production)

Практика:

  • в библиотеках — осторожно с ^;
  • в приложениях — фиксируйте lock-файл и проверяйте npm outdated перед обновлениями.
npm outdated
npm update

npm update поднимает версии в пределах диапазонов из package.json и обновляет lock.


Скрипты в package.json

Скрипты в package.json — это специальный раздел в файле package.json, который позволяет разработчикам определять и хранить произвольные командные строки для автоматизации рутинных задач, таких как запуск приложения, сборка проекта, запуск тестов, линтинг кода, миграция базы данных и другие операции, делая их легко выполнимыми через единый интерфейс команды npm run. Каждый скрипт представляет собой пару ключ-значение, где ключом является имя скрипта, а значением — строка с командой, которая будет выполнена в командной оболочке операционной системы, причем эти скрипты могут вызывать как системные утилиты, так и исполняемые файлы, установленные локально в папке node_modules. Существует несколько предопределенных скриптов, которые имеют особое значение в экосистеме npm, например, скрипт start, который вызывается командой npm start без слова run, и скрипт test, который запускается командой npm test, что делает эти команды еще более удобными и общепринятыми для запуска приложений и тестов соответственно. Скрипты обладают важной особенностью: при их выполнении npm автоматически добавляет в переменную окружения PATH пути к исполняемым файлам, находящимся в папке node_modules/.bin, что позволяет вызывать установленные локально пакеты напрямую по их именам без указания полного пути, например, запускать webpack, eslint, mocha и другие инструменты, установленные как зависимости разработки. Скрипты могут быть скомбинированы и последовательно вызывать друг друга с помощью специальных синтаксических конструкций, таких как двойной амперсанд для последовательного выполнения или одинарный амперсанд для параллельного выполнения на Unix-системах, а также могут принимать аргументы, которые передаются после двойного дефиса, позволяя гибко настраивать их поведение при каждом вызове. Использование скриптов в package.json является индустриальным стандартом и считается хорошей практикой, поскольку оно централизует все команды для работы с проектом в одном файле, облегчает введение новых разработчиков в проект, обеспечивает единообразие выполнения задач на разных машинах и в системах непрерывной интеграции, а также избавляет разработчиков от необходимости запоминать длинные и сложные команды с множеством опций.

{
"scripts": {
"dev": "nodemon src/index.js",
"start": "node src/index.js",
"test": "node --test",
"lint": "eslint ."
}
}
npm run dev
npm start
npm test

Разбор:

  • npm run <имя> выполняет команду из scripts и добавляет node_modules/.bin в PATH.
  • npm start и npm test — сокращения для npm run start / npm run test (если скрипт объявлен).
  • Префиксы pre / post: prebuild запустится перед build, postinstall — после npm install.

Переменные окружения в скриптах:

  • Unix: NODE_ENV=production node app.js
  • Windows cmd: set NODE_ENV=production && node app.js
  • Кроссплатформенно: пакет cross-envcross-env NODE_ENV=production node app.js

Подробнее про порядок скриптов в команде — CLI и деплой.


Безопасность и аудит

npm audit — это встроенный инструмент безопасности в менеджере пакетов npm, который анализирует дерево зависимостей проекта на наличие известных уязвимостей, сверяя установленные версии пакетов с общедоступной базой данных уязвимостей, поддерживаемой GitHub и командой npm, и предоставляет детальный отчет о найденных проблемах с рекомендациями по их устранению. При выполнении команды npm audit менеджер сканирует все пакеты, установленные в проекте, включая транзитивные зависимости, и сопоставляет их версии с записями в реестре уязвимостей, которые содержат информацию о том, в каких версиях была обнаружена уязвимость и в каких версиях она была исправлена, после чего формирует отчет, классифицируя уязвимости по уровню серьезности: критический, высокий, средний и низкий. На основе полученного отчета разработчик может принять решение об обновлении проблемных пакетов до версий, в которых уязвимость устранена, используя команду npm audit fix, которая автоматически пытается обновить зависимости до безопасных версий без нарушения семантического версионирования, или npm audit fix --force, которая может обновить пакеты с изменением мажорной версии, что потенциально может привести к ломающим изменениям в приложении. Инструмент также предоставляет возможность получить более детальную информацию о каждой конкретной уязвимости, включая описание проблемы, ссылки на соответствующие CVE-записи, рекомендации по исправлению и информацию о том, какой именно пакет в дереве зависимостей вызывает данную уязвимость. Важно понимать, что npm audit не гарантирует абсолютной безопасности, поскольку он полагается на базу данных известных уязвимостей, которая не может покрыть все возможные проблемы, особенно нулевого дня, однако регулярное использование этого инструмента является обязательной практикой для поддержания приемлемого уровня безопасности в любом производственном проекте. Современные системы непрерывной интеграции часто включают npm audit в свои пайплайны, чтобы автоматически проверять безопасность зависимостей при каждом коммите или сборке, предотвращая попадание уязвимых пакетов в продакшен-окружение.

npm audit
npm audit fix
npm audit fix --force

Разбор:

  • npm audit сравнивает дерево зависимостей с базой уязвимостей.
  • npm audit fix обновляет совместимые патчи автоматически.
  • --force может поднять major-версии — проверяйте тесты после.

Дополнительно — Dependabot, Snyk, политики в корпоративном npm Enterprise.

npm license

Показывает лицензии зависимостей — важно для compliance.


Публикация пакета

Если вы делаете библиотеку для других команд, после npm login достаточно npm publish на npmjs.com (для открытых пакетов — бесплатно). Имя в package.json должно быть уникальным; поле "files" задаёт, что попадёт в архив.

npm login
npm publish

В учебных API-проектах публикация в npm обычно не требуется — храните код в Git.


npm, yarn и pnpm

yarn — это альтернативный менеджер пакетов для экосистемы Node.js, созданный компанией Facebook в 2016 году в ответ на проблемы производительности, безопасности и недетерминированности установки, существовавшие в старых версиях npm, и предлагающий более быструю и надежную работу за счет параллельной загрузки пакетов, агрессивного кеширования и использования файла yarn.lock для точной фиксации версий всех зависимостей. Одним из ключевых нововведений yarn стала концепция офлайн-кеша, которая сохраняет все загруженные пакеты в глобальной директории, благодаря чему при повторной установке тех же зависимостей они не скачиваются заново, что значительно ускоряет процесс установки в проектах с большим количеством пакетов или при частой смене веток в системе контроля версий. yarn также внедрил более строгую и надежную логику разрешения зависимостей, которая гарантирует, что установка на разных машинах всегда будет приводить к идентичному дереву пакетов, что полностью устраняет проблему недетерминированных сборок, когда разные разработчики или окружения получали разные наборы версий из-за особенностей алгоритма установки. Синтаксис команд yarn очень похож на npm, что делает переход между ними практически безболезненным, но некоторые команды отличаются или имеют дополнительные возможности, например, команда yarn add для установки пакетов, yarn upgrade для обновления, а также уникальные команды, такие как yarn why, которая позволяет узнать, почему в проекте установлен тот или иной пакет, и yarn interactive, предоставляющая интерактивный интерфейс для управления зависимостями. yarn также поддерживает рабочие пространства, представляющие собой встроенный монорепозиторный механизм, позволяющий управлять несколькими пакетами в одном репозитории с единой системой управления зависимостями, что делает его особенно популярным в крупных проектах с разделенной архитектурой и микросервисным подходом. Со временем yarn развивался и в версии 2 и 3, известных как yarn Berry, перешел на более современную архитектуру с поддержкой плагинов, использованием системы Plug'n'Play для ускорения загрузки модулей и отказом от папки node_modules в пользу глобального хранилища, хотя это нововведение вызвало споры в сообществе и многие проекты продолжают использовать классическую версию yarn Classic.

pnpm — это современный, высокопроизводительный менеджер пакетов для Node.js, который отличается от npm и yarn своим уникальным подходом к хранению зависимостей, основанным на жестких ссылках и символьных ссылках, что позволяет существенно экономить дисковое пространство и ускорять процесс установки за счет глобального хранилища всех версий пакетов и создания только необходимых ссылок внутри проекта. Основная инновация pnpm заключается в том, что все пакеты скачиваются и сохраняются в централизованном глобальном кеше только один раз, независимо от того, сколько проектов их используют, а в папке node_modules каждого конкретного проекта создаются жесткие ссылки на эти файлы, благодаря чему повторяющиеся зависимости не занимают дополнительное место на диске и установка происходит практически мгновенно, если все нужные пакеты уже есть в кеше. В отличие от плоской структуры node_modules, которую используют npm и yarn, pnpm создает строгую иерархическую структуру, которая точно соответствует дереву зависимостей, размещая каждую зависимость в своей собственной папке и используя символьные ссылки для разрешения зависимостей, что предотвращает случайное использование пакетов, которые не объявлены явно в package.json, и тем самым повышает строгость и надежность управления зависимостями. Такой подход также решает проблему "призрачных зависимостей", когда проект может неявно использовать пакеты, которые не указаны в его зависимостях, но присутствуют в node_modules благодаря транзитивным зависимостям, что приводит к ошибкам при переносе проекта на другие окружения или при обновлении пакетов. pnpm полностью совместим с экосистемой npm, поддерживает файлы package.json и package-lock.json, а также все основные команды, такие как install, add, update, remove, audit, и может использоваться как прямая замена npm или yarn в большинстве проектов без изменения кода или конфигурации. Благодаря своей экономичности по отношению к дисковому пространству и скорости работы, pnpm становится все более популярным выбором для проектов с большим количеством зависимостей, монорепозиториев и сред непрерывной интеграции, где каждая секунда и каждый мегабайт имеют значение, и многие крупные компании постепенно переходят на этот менеджер в своих инфраструктурах.

КритерийnpmYarn (Berry)pnpm
Lock-файлpackage-lock.jsonyarn.lockpnpm-lock.yaml
СкоростьХорошаяОчень быстрая (Berry)Часто самая быстрая
ДискДубли версийЗависит от режимаОдин store + ссылки
Workspacesnpm 7+ДаСтабильные monorepo
Когда братьСтандарт, GitHub PackagesZero-install, strictMonorepo, CI с лимитом диска

Все три читают один package.json. Смена менеджера: удалить node_modules и чужой lock, затем install новым инструментом.


Типичные ошибки

СимптомПричинаРешение
Cannot find moduleНет установкиnpm install в корне с package.json
Разные версии у коллегНет lock в GitКоммитить package-lock.json, в CI — npm ci
ERESOLVEКонфликт peer dependenciesЧитать лог, выровнять версии или --legacy-peer-deps (временно)
Скрипт не найденОпечатка в scriptsnpm run без аргумента покажет список
Глобальный пакет не находится в PATHPATHnpx или локальный devDependency
npx create-vite@latest my-app

npx скачивает и запускает CLI без глобальной установки.


Связанные материалы

ТемаМатериал
Папки src/, config/, конвенцииСтруктура Node-проекта и правила разработки
node --watch, Docker, PM2CLI Node.js — запуск, отладка и деплой
Первая программа с ExpressПервая программа на Node.js
Таблицы APIСправочник по Node

Основа по протоколу

Базовый разбор HTTP и HTTPS — HTTP как основа веб-интеграций.