EvolCode
треки/Инструменты вайбкодера·03 / 05
11 мин чтения

npm и зависимости — без сломанного node_modules

npm install — самая часто запускаемая команда у вайбкодера. И самая часто ломающая проект. Понять как именно npm работает — час работы, и потом не теряешь дни на «у меня в node_modules какой-то ад». Разбираем package.json, lockfile, semver-диапазоны и команды которые спасают.

package.json и lockfile — два разных файла, оба важны

package.json описывает что НУЖНО: «react любая версия 18.x.x». Это твой манифест. package-lock.json фиксирует что РЕАЛЬНО установлено: «react 18.3.1, точная версия со всеми её зависимостями». Когда ты делаешь npm install, npm читает lockfile и ставит ИМЕННО те версии. Без lockfile у двух разработчиков могут быть разные версии библиотек и баги «у меня работает». Lockfile ОБЯЗАТЕЛЬНО коммитится в git.

Semver — что значат ^ и ~ перед версией

В package.json видишь "react": "^18.3.1". Это semver-диапазон: ^ значит «можно обновлять минорную и патч-версию, но не мажорную». То есть ^18.3.1 разрешит обновиться до 18.5.0 или 18.9.99, но не до 19.0.0. ~ значит только патч: ~18.3.1 разрешит 18.3.5 но не 18.4.0. Без префикса — точная версия (никогда не обновится автоматически). Правило: ^ для большинства зависимостей, ~ для библиотек с историей ломающих минор-релизов, без префикса для критичных штук типа Next.js.

dependencies vs devDependencies

dependencies — то что нужно в проде (react, next, prisma client). devDependencies — то что нужно ТОЛЬКО при разработке (typescript, eslint, vitest, prettier). Когда ты деплоишь на Vercel/прод, можно поставить с флагом --production и devDependencies не установятся. Это экономит размер билда и время. Ошибка в которую все падают — кладут @types/* в dependencies. @types нужны только при компиляции, на проде не нужны → должны быть в devDependencies. Правильно:

$ npm i -D @types/node

(флаг -D = devDependencies).

Команды первой необходимости

$ npm install

поставить из package.json + lockfile.

$ npm i <pkg>

добавить новую.

$ npm i -D <pkg>

добавить как dev.

$ npm uninstall <pkg>

удалить.

$ npm outdated

показать какие зависимости устарели и насколько.

$ npm update

обновить в рамках semver-диапазона (без поломок мажорных).

$ npm audit

проверить уязвимости.

$ npm audit fix

попытаться починить автоматически.

$ npm ci

то же что install но БЕЗ обновления lockfile, для CI и серверных билдов чтобы быть уверенным что устанавливается ровно то что в lockfile.

Что делать когда node_modules сломался

Универсальная процедура «всё сломалось»: (1) Удалить node_modules целиком:

$ rm -rf node_modules

(2) Удалить lockfile:

$ rm package-lock.json

(3)

$ npm install

пересоберёт всё с нуля. В 80% случаев решает проблему. Если не помогло: (4) Очистить npm cache:

$ npm cache clean --force

(5) Проверить версию Node:

$ node -v

она в .nvmrc или engines в package.json. Несовпадение версий — частая причина странных ошибок. (6) Если на маке проблема с native modules (sharp, bcrypt) —

$ npm rebuild
примерjson
{
  "name": "my-app",
  "version": "0.1.0",
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "typecheck": "tsc --noEmit",
    "db:push": "prisma db push",
    "db:studio": "prisma studio"
  },

  "// dependencies": "Нужно для работы прода",
  "dependencies": {
    "next": "14.2.15",
    "react": "^18.3.1",
    "@prisma/client": "^5.22.0",
    "next-auth": "^4.24.10",
    "bcryptjs": "^2.4.3"
  },

  "// devDependencies": "Только разработка — НЕ попадает в прод-билд",
  "devDependencies": {
    "typescript": "^5",
    "@types/node": "^20",
    "@types/react": "^18",
    "@types/bcryptjs": "^2.4.6",
    "eslint": "^8",
    "eslint-config-next": "14.2.15",
    "prisma": "^5.22.0"
  },

  "// engines": "Версия Node которую требует проект",
  "engines": {
    "node": ">=18.18.0"
  }
}

package.json — что где должно лежать

главное
  • 01package.json = что нужно. package-lock.json = что точно установлено. Lockfile коммитится в git.
  • 02Semver: ^ = минорные обновления, ~ = только патч, без префикса = точно эта версия.
  • 03@types/* и сборочные тулы → devDependencies. На проде их не нужно качать.
  • 04npm ci для CI/серверов (детерминированная установка), npm install для разработки.
  • 05Сломалось всё? → rm -rf node_modules + rm package-lock.json + npm i. В 80% случаев чинит.
проверь себя
01В чём разница "^18.3.1" и "~18.3.1" в package.json?
02Куда положить @types/node — в dependencies или devDependencies?
03Какая команда даёт детерминированную установку (ровно как в lockfile)?
следующий урок: Читать ошибки как взрослый