9

Почему "npm install" перезаписывает package-lock.json?

11

Я недавно обновился до npm@5. Теперь у меня есть файл package-lock.json, который содержит все зависимости из package.json. Я ожидал, что при запуске команды npm install версии зависимостей будут подтягиваться из lock-файла для определения того, что должно быть установлено в моем каталоге node_modules. Однако странно, что в процессе установки мой файл package-lock.json фактически модифицируется и перезаписывается.

Например, в lock-файле была указана версия typescript 2.1.6. Однако после запуска команды npm install версия изменилась на 2.4.1. Это кажется противоречащим самой сути lock-файла.

Что я упускаю? Как заставить npm действительно уважать мой lock-файл?

5 ответ(ов)

1

Краткий ответ:

  • npm install учитывает package-lock.json только в том случае, если он соответствует требованиям из package.json.
  • Если требования не удовлетворяются, пакеты обновляются, и package-lock.json перезаписывается.
  • Если вы хотите, чтобы установка завершалась с ошибкой вместо перезаписи package-lock.json, используйте npm ci.

Вот сценарий, который может прояснить ситуацию (проверено на NPM 6.3.0)

Вы объявляете зависимость в package.json следующим образом:

"depA": "^1.0.0"

После этого выполняете npm install, что сгенерирует package-lock.json с:

"depA": "1.0.0"

Через несколько дней выходит новая минорная версия depA, скажем, 1.1.0, и тогда будет верно следующее:

npm ci       # учитывает только package-lock.json и устанавливает 1.0.0

npm install  # также учитывает версию из package-lock и оставляет 1.0.0 установленным 
             # (то есть, когда существует package-lock.json, он имеет приоритет над package.json)

Далее вы вручную обновляете свой package.json до:

"depA": "^1.1.0"

Затем снова выполняете:

npm ci      # попытается учесть package-lock, который говорит 1.0.0
            # но это не удовлетворяет требованию package.json "^1.1.0" 
            # поэтому возникнет ошибка 

npm install # установит "1.1.0" (как требуется обновленным package.json)
            # также перепишет версию в package-lock.json на "1.1.0"
            # (то есть, когда package.json изменяется, он переопределяет package-lock.json)
0

В будущем вы сможете использовать флаг --from-lock-file (или аналогичный) для установки только из файла package-lock.json, не модифицируя его.

Это будет полезно для CI и других окружений, где важна воспроизводимость сборок.

Подробности отслеживания этой функции можно найти по ссылке: https://github.com/npm/npm/issues/18286.

0

Похоже, что эта проблема была исправлена в версии npm 5.4.2.

https://github.com/npm/npm/issues/17979

(Прокрутите вниз до последнего комментария в обсуждении)

Обновление

На самом деле исправление вышло в версии 5.6.0. В версии 5.4.2 была ошибка, связанная с кросс-платформенной совместимостью, из-за которой проблема все еще могла возникать.

https://github.com/npm/npm/issues/18712

Обновление 2

Смотрите мой ответ здесь: https://stackoverflow.com/a/53680257/1611058

Теперь командой, которую следует использовать для установки существующих проектов, является npm ci.

0

Вероятно, вам стоит использовать что-то вроде этого:

npm ci

Вместо того, чтобы использовать npm install, если вы не хотите изменять версию вашего пакета.

Согласно официальной документации, как npm install, так и npm ci устанавливают зависимости, необходимые для проекта.

Основное различие заключается в том, что npm install устанавливает пакеты, принимая за основу файл package.json. В то время как в случае npm ci установка пакетов осуществляется на основе файла package-lock.json, что гарантирует, что каждый раз устанавливается именно тот же самый пакет.

0

Этот сайт также содержит информацию о изменениях в package-lock при последующих выполениях команды npm i: GitHub - npm/cli#4263.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь