Урок по треку Инструменты 6 мин

npm, semver и lock-файлы

package.json, semver, lock-файлы, npm, pnpm и Yarn, peer-зависимости и монорепо.

package.json

Паспорт проекта: имя, версия, скрипты и зависимости.

{
  "name": "shop-web",
  "type": "module",
  "scripts": { "dev": "vite", "build": "vite build", "test": "vitest" },
  "dependencies": { "react": "^19.0.0" },
  "devDependencies": { "vite": "^7.0.0", "typescript": "~5.8.0" },
  "peerDependencies": {}
}
  • dependencies: нужны коду в рантайме.
  • devDependencies: нужны только для разработки и сборки (сборщик, линтер, тесты). npm install --omit=dev их не ставит.
  • peerDependencies: «я плагин, хозяин должен сам поставить вот это». Например, библиотека компонентов требует react, но не тащит свою копию, чтобы в приложении не оказалось двух React. npm начиная с 7 версии ставит peer-зависимости автоматически и ругается на конфликт версий.

npm run <script> запускает скрипт, при этом node_modules/.bin попадает в PATH, поэтому в скриптах пишут просто vite, а не путь к нему. npx <cmd> запускает бинарь пакета, при необходимости скачав его.

Semver

Версия MAJOR.MINOR.PATCH: major ломает обратную совместимость, minor добавляет возможности, patch исправляет баги.

ЗаписьЧто разрешено
1.4.2ровно 1.4.2
^1.4.2>=1.4.2 <2.0.0
~1.4.2>=1.4.2 <1.5.0
^0.4.2>=0.4.2 <0.5.0 (для 0.x каретка консервативнее)

npm install по умолчанию записывает ^. Но semver это обещание автора, а не гарантия: minor-релиз тоже может сломать.

Lock-файл

package-lock.json (pnpm-lock.yaml, yarn.lock) фиксирует точные версии всего дерева, включая транзитивные зависимости, и хеши целостности. Без него два разработчика с одинаковым package.json в разное время получат разные версии.

  • Lock-файл коммитят в репозиторий приложения.
  • npm install может обновить lock, если package.json изменился.
  • npm ci ставит строго по lock-файлу, предварительно удаляя node_modules, и падает, если lock не соответствует package.json. Это команда для CI и Docker.

npm, pnpm, Yarn

  • npm идёт с Node.js, кладёт пакеты «плоско» в node_modules.
  • pnpm хранит каждую версию пакета один раз в глобальном хранилище и ставит через ссылки: быстро и экономно по диску. Его node_modules строгий: код видит только то, что объявлено в его package.json.
  • Yarn (Berry) умеет Plug'n'Play без папки node_modules.

Плоский node_modules npm создаёт проблему фантомных зависимостей: ты импортируешь пакет, который не объявлен у тебя, а просто оказался в корне как зависимость другого пакета. Работает до первого обновления.

Монорепо и workspaces

Workspaces ("workspaces": ["packages/*"] в npm и Yarn, pnpm-workspace.yaml в pnpm) позволяют держать несколько пакетов в одном репозитории, связывать их между собой ссылками и ставить зависимости одной командой. Для оркестрации задач поверх добавляют Turborepo или Nx.

Безопасность

  • npm audit показывает известные уязвимости в дереве.
  • Скрипты postinstall выполняются при установке: вредоносный пакет может украсть секреты. Свежие версии pnpm по умолчанию не запускают скрипты зависимостей, пока ты их явно не разрешишь.
  • Опечатки в имени пакета (typosquatting) реальная атака.

Частые ошибки

  • Не коммитить lock-файл или делать npm install в CI вместо npm ci.
  • Класть сборщик в dependencies, а react в devDependencies у библиотеки вместо peerDependencies.
  • Импортировать пакет, которого нет в своём package.json.

Что спросят на собесе

  • Разница dependencies, devDependencies, peerDependencies.
  • Что значат ^ и ~.
  • Зачем lock-файл и чем npm ci отличается от npm install.
  • Чем pnpm отличается от npm.
  • Что такое фантомные зависимости.

Закрепите за 5 минут

После урока в тренажёре 3-5 проверочных вопросов, дальше модуль уходит в повторения.