В чем разница между «npm install» и «npm ci»?


215

Я работаю с непрерывной интеграцией и обнаружил команду npm ci .

Я не могу понять, каковы преимущества использования этой команды для моего рабочего процесса.

Это быстрее? Это делает тест более сложным, хорошо, и после?

Ответы:


328

Из документов npm :

Короче говоря, основные различия между использованием npm install и npm ci:

  • Проект должен иметь существующий пакет-lock.json или npm-shrinkwrap.json.
  • Если зависимости в блокировке пакета не совпадают с зависимостями в package.json, npm ci выйдет с ошибкой вместо обновления блокировки пакета.
  • npm ci может устанавливать только целые проекты за раз: с помощью этой команды нельзя добавить отдельные зависимости.
  • Если node_modules уже присутствует, он будет автоматически удален до того, как npm ci начнет его установку.
  • Он никогда не будет писать в package.json или любой из блокировок пакетов: установки по сути заморожены.

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

npm ci(названный в честь C ontinuous I ntegration) устанавливает зависимости непосредственно от package-lock.jsonи использует package.jsonтолько для проверки , что нет несовпадения версий. Если какие-либо зависимости отсутствуют или имеют несовместимые версии, возникнет ошибка .

Используйте npm installдля добавления новых зависимостей и для обновления зависимостей в проекте. Обычно вы используете его во время разработки после внесения изменений, которые обновляют список зависимостей, но npm ciв этом случае это может быть хорошая идея .

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

npm install

  • Устанавливает пакет и все его зависимости.
  • Зависимости обусловлены npm-shrinkwrap.jsonи package-lock.json(в этом порядке).
  • без аргументов : устанавливает зависимости локального модуля.
  • Можно установить глобальные пакеты.
  • Устанавливаем любые недостающие зависимости в node_modules.
  • Это может написать package.jsonили package-lock.json.
    • При использовании с аргументом ( npm i packagename) он может писать package.jsonдля добавления или обновления зависимости.
    • при использовании без аргументов ( npm i) он может писать в, package-lock.jsonчтобы заблокировать версию некоторых зависимостей, если их еще нет в этом файле.

npm ci

  • Требуется как минимум npm v5.7.1 .
  • Требуется package-lock.jsonили npm-shrinkwrap.jsonприсутствовать.
  • Выдает ошибку, если зависимости из этих двух файлов не совпадают package.json.
  • Удаляет node_modulesи устанавливает все зависимости сразу.
  • Он никогда не пишет package.jsonили package-lock.json.

Алгоритм

Хотя npm ciгенерирует все дерево зависимостей из package-lock.jsonили npm-shrinkwrap.json, npm install обновляет содержимое,node_modules используя следующий алгоритм ( источник ):

load the existing node_modules tree from disk
clone the tree
fetch the package.json and assorted metadata and add it to the clone
walk the clone and add any missing dependencies
  dependencies will be added as close to the top as is possible
  without breaking any other modules
compare the original tree with the cloned tree and make a list of
actions to take to convert one to the other
execute all of the actions, deepest first
  kinds of actions are install, update, remove and move

1
Я не знал, npm installмог написать в package.json. Вы знаете, что здесь можно написать?
Veve

5
Что ж, это может немного вводить в заблуждение ... он будет писать в package.json, когда вы используете его для установки, обновления или удаления зависимостей. Я сделаю это более ясно в тексте, спасибо!
Lucascaro

Где этот алгоритм задокументирован? Т.е. каков твой источник?
Ингвар Кристиансен

1
@YngvarKristiansen это в документации npm, добавил ссылку на конкретный раздел для справки
lucascaro

4
npm install packageмог изменить и то, package-lock.json и другое package.json, в то время как npm installаргументы без изменений только изменились быpackage-lock.json
knobo

20

npm ciудалит любую существующую папку node_modules и использует package-lock.jsonфайл для установки конкретной версии каждого пакета. Это значительно быстрее, чем установка npm, потому что пропускает некоторые функции. Установка в чистом виде отлично подходит для конвейеров ci / cd и сборок докеров! Вы также используете его для установки всего сразу, а не конкретных пакетов.


9

Документация, на которую вы ссылались, содержала резюме:

Короче говоря, основные различия между использованием npm install и npm ci:

  • Проект должен иметь существующий пакет-lock.json или npm-shrinkwrap.json.
  • Если зависимости в блокировке пакета не совпадают с зависимостями в package.json, npm ci выйдет с ошибкой вместо обновления блокировки пакета.
  • npm ci может устанавливать только целые проекты за раз: с помощью этой команды нельзя добавить отдельные зависимости.
  • Если node_modules уже присутствует, он будет автоматически удален до того, как npm ci начнет его установку.
  • Он никогда не будет писать в package.json или любой из блокировок пакетов: установки по сути заморожены.

2

Команды очень похожи по функциональности, однако разница заключается в подходе, который используется для установки зависимостей, указанных в ваших файлах package.jsonи package-lock.jsonфайлах.

npm ciвыполняет чистую установку всех зависимостей вашего приложения, тогда как npm installможет пропустить некоторые установки, если они уже существуют в системе. Проблема может возникнуть, если версия, уже установленная в системе, не является той, которую вы package.jsonнамеревались установить, т.е. установленная версия отличается от « требуемой » версии.

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

Вы можете прочитать намного лучшее объяснение от официальных документов здесь .

Кроме того, вы можете прочитать о блокировках пакетов здесь .


1

Стоит иметь в виду, что на изображениях док-станции легких узлов, таких как alpine, не установлен Python, зависимость от node-gypкоторого используется npm ci.

Я думаю, что это несколько сомнительно, что для того, чтобы npm ciработать, вам нужно установить Python в качестве зависимости в вашей сборке.

Больше информации здесь Docker и npm - gyp ERR! не в порядке


0

В то время как все остальные ответили на технические различия, никто не объясняет, в каких ситуациях использовать оба.

Вы должны использовать их в разных ситуациях.

npm installотлично подходит для разработки и в CI, когда вы хотите кэшировать node_modulesкаталог. Когда это использовать? Вы можете сделать это, если вы делаете пакет для использования другими людьми (вы НЕ включаете node_modulesв такой выпуск) . Что касается кэширования, будьте осторожны, если вы планируете поддерживать разные версии Node.jsзапоминания, которые, node_modulesвозможно, придется переустанавливать из-за различий между Node.jsтребованиями времени выполнения. Если вы хотите придерживаться одной версии, придерживайтесь последней LTS.

npm ciследует использовать, когда вы хотите протестировать и выпустить производственное приложение (конечный продукт, который не будет использоваться другими пакетами), поскольку важно, чтобы установка была как можно более детерминированной, эта установка займет больше времени, но в конечном итоге ваше приложение более надежно (вы включаете node_modulesв такой релиз) . Палка с LTSверсией Node.js.

Бонус: вы можете смешивать их в зависимости от того, насколько сложным вы хотите это сделать. В функциональных ветвях gitвы можете кэшировать их, node_modulesчтобы повысить производительность своих команд, а в запросах на слияние и в основных ветвях полагаться на npm ciопределенный результат.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.