В чем разница package-lock.json и package.json
Что проверяют
Понимаете ли вы, почему сборка у коллеги и в CI может отличаться от вашей. Вопрос про воспроизводимость окружения, а не про формат файлов.
Как отвечать
package.json это описание проекта: имя, версия, скрипты и объявленные зависимости с диапазонами версий (^1.2.0 разрешает любую версию до второй мажорной, ~1.2.0 только патчи). Он говорит, что вам подходит.
package-lock.json это снимок фактически установленного дерева: точные версии всех пакетов, включая транзитивные, их адреса и контрольные суммы. Он говорит, что именно установлено.
Отсюда практические следствия:
- lock-файл коммитится в репозиторий. Без него
npm installу коллеги через месяц подтянет более свежие версии внутри диапазона, и вы получите разное поведение при одинаковом коде; - в CI и в образе используется
npm ci, а неnpm install: он ставит ровно то, что в lock-файле, падает при расхождении сpackage.jsonи не изменяет lock; - обновление осознанное:
npm update,npm install пакет@версияили инструменты вроде Renovate, и результат виден в диффе lock-файла; - безопасность: контрольные суммы в lock защищают от подмены содержимого пакета, а
npm auditработает по этому же дереву.
Стоит упомянуть, что аналогичные файлы есть у других менеджеров (yarn.lock, pnpm-lock.yaml), и держать в проекте два разных lock-файла одновременно нельзя: они разъедутся.
Где спотыкаются
Добавляют lock-файл в .gitignore и теряют воспроизводимость.
Разрешают конфликт в lock-файле вручную. Правильнее принять одну версию и перегенерировать его установкой.
Считают npm ci просто более быстрым npm install. Он ещё и строгий: удаляет node_modules и не чинит рассогласование, а сообщает о нём.