В чем разница между Package.json и Package-lock.json

Ответ

package.json — это файл, описывающий зависимости проекта (dependencies и devDependencies) и метаданные (версия, скрипты и т. д.). Версии зависимостей могут указываться с гибкими диапазонами (^, ~), что позволяет устанавливать обновления в пределах мажорной/минорной версии.

package-lock.json автоматически генерируется при установке пакетов (npm install) и фиксирует точные версии всех зависимостей, включая вложенные. Это гарантирует воспроизводимость сборки: у всех разработчиков будут одинаковые версии пакетов.

Пример:
В package.json:

"dependencies": {
  "lodash": "^4.17.0"
}

В package-lock.json будет указана точная версия, например 4.17.21, и все её подзависимости.

Важно:

  • package-lock.json нельзя редактировать вручную.
  • При коммите в репозиторий его нужно включать, чтобы избежать "works on my machine" проблем.
  • npm ci использует package-lock.json для точной установки версий, в отличие от npm install.

Ответ 18+ 🔞

Да ты посмотри, что эти фронтендеры вытворяют, блядь! Сидят, два файла на один и тот же проект завели, и оба вроде как про зависимости. Ну пиздец, ёпта, мозги сломать можно.

Смотри, вот package.json — это типа такой официальный, приличный документ. Там всё красиво: название проекта, версия, и главное — список, кто ему нужен для работы. Типа «мне нужен lodash, версии от 4.17.0 и выше, но только не пятая, а то там всё поломают». Пишет "^4.17.0" и думает, что он гибкий и современный, блядь.

А потом приходит этот ёбаный npm install и говорит: «Ага, щас я тебе всё красиво соберу». И нахуяривает рядом package-lock.json. Это уже не документ, а, блядь, полный протокол допроса со всеми уликами! Там уже не «lodash где-то от 4.17», а «lodash версия ровно 4.17.21, и у него есть друг chalk версии 2.4.2, а у того, в свою очередь, троюродный брат ansi-styles...». Короче, полная схема всех связей, до самого дна, сука.

И вот в чём, блядь, главный прикол. У тебя на компе стоит lodash 4.17.21, и всё летает. А твой коллега, такой же распиздяй, делает npm install, и ему npm, такой добрый, подсовывает уже 4.17.22, которую только что выпустили. А там, оказывается, одна функция так по-тихому сломалась. И всё, пиздец, Колян! У него не работает, у тебя работает. Начинается: «Да у меня же всё ок!», «А у меня нет!». А виноват-то кто? Правильно, отсутствие package-lock.json в гите, блядь!

Поэтому запомни, как «Отче наш»:

  1. package-lock.json — это святое, его в репозиторий коммитить ОБЯЗАТЕЛЬНО. Это как закон, блядь. Чтобы у всех один и тот же бардак был.
  2. Руками его не трогай, ёбта! Он самогенерируемый. Ты его тронешь — всё, ты конченый.
  3. Хочешь точную сборку, как в замке? Не npm install, а npm ci. Эта команда тупо берет package-lock.json и ставит ВСЁ ТОЧНО ТАК, как там написано. Никаких «а может, вот эту версию новенькую?». Быстро и четко, в рот меня чих-пых!

Краткий пример, чтобы вообще мозг встал на место:

В package.json у тебя:

"dependencies": {
  "lodash": "^4.17.0"
}

А в package-lock.json уже будет такая простыня:

{
  "name": "my-project",
  "version": "1.0.0",
  "lockfileVersion": 2,
  "requires": true,
  "dependencies": {
    "lodash": {
      "version": "4.17.21",
      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
    }
  }
}

Видишь разницу? В первом — «дай что-нибудь из этой серии». Во втором — «дай конкретно вот этот архив с этой контрольной суммой, и чтобы ни байта не отличалось!».

Вот так и живём. Один файл для вежливой просьбы, другой — для жёсткой фиксации реальности, блядь. Главное — не перепутать, когда что использовать, а то будет волнение ебать.