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

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

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

Это быстрее? Это усложняет тест, а потом?


person Webwoman    schedule 25.09.2018    source источник


Ответы (6)


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

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

  • У проекта должен быть существующий package-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 (названный в честь постоянной интеграции) устанавливает зависимости непосредственно из package-lock.json и использует package.json только для проверки отсутствия несовпадающих версий. Если какие-либо зависимости отсутствуют или имеют несовместимые версии, будет выдана ошибка.

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

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

npm install

  • Устанавливает пакет и все его зависимости.
  • Зависимости управляются npm-shrinkwrap.json и package-lock.json (в этом порядке).
  • без аргументов: устанавливает зависимости локального модуля.
  • Может устанавливать глобальные пакеты.
  • Установит все недостающие зависимости в node_modules.
  • It may write to package.json or package-lock.json.
    • When used with an argument (npm i packagename) it may write to package.json to add or update the dependency.
    • при использовании без аргументов (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
person lucascaro    schedule 15.11.2018
comment
Я не знал, что npm install может писать в package.json. Вы знаете, что здесь могло быть написано? - person Veve; 15.11.2018
comment
что ж, это может ввести в заблуждение ... он будет писать в package.json, когда вы используете его для установки, обновления или удаления зависимостей. Я проясню это в тексте, спасибо! - person lucascaro; 15.11.2018
comment
npm install package может изменять как package-lock.json , так и package.json, а npm install без аргументов изменяет только package-lock.json - person knobo; 08.08.2019
comment
Недавно я обнаружил, что если мы хотим, чтобы npm не устанавливал недостающие зависимости из package-lock.json, мы можем переписать "require": true" в package-lock.json. - person PuiMan Cheui; 21.01.2020
comment
Как работает кеш? Будет ли он медленнее или быстрее по сравнению со старым npm install? - person BMW; 22.01.2020
comment
Я считаю, что одно из различий также в том, что npm install устанавливает devDependencies, а npm ci нет, насколько я понимаю. - person Link14; 23.01.2020
comment
@ Link14 установка devDependencies управляется флагом --production или переменной среды NODE_ENV как для npm i, так и для npm ci - person lucascaro; 17.02.2020
comment
Хотя нигде в документации явно не сказано, ci в npm ci лучше понимать как чистую установку, а не непрерывную интеграцию. - person William Denman; 05.03.2021
comment
in short не короткий .. - person user218867; 10.05.2021
comment
Как насчет использования обоих, хостинг firebase по умолчанию для обоих для команды сборки - person Maverick; 09.07.2021

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

person James Harrison    schedule 25.09.2018
comment
Удаление ранее существовавших node_modules может значительно замедлить сборку - person jontro; 20.08.2020
comment
Может быть, не фиксировать node_modules? - person Cameron Gilbert; 02.07.2021

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

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

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

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

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

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 для детерминированного результата.

person basickarl    schedule 06.05.2020
comment
Я не думаю, что существует какой-либо сценарий, в котором npm i следует использовать вместо npm ci, кроме случаев, когда вы хотите обновить свои зависимости. npm ci всегда лучше, потому что детерминированное поведение всегда лучше - person enanone; 20.03.2021
comment
@enanone Как я уже сказал, npm i кеширует, поскольку он быстрее, npm ci медленнее, так как он выполняет полную переустановку. Они оба полезны. - person basickarl; 23.03.2021
comment
npm ci работает так же быстро, если каждый пакет находится в кеше npm - person enanone; 23.03.2021
comment
В моем случае npm ci значительно медленнее, даже если это делается многократно, с локальным кешем NPM: npm install составляет около 2 с, npm ci 16 с при запуске для того же проекта. После очистки кеша они такие же. Нам отчаянно нужно что-то, что можно было бы установить из package-lock, но не начинайте с удаления node_modules: github. ru / npm / cli / issues / 564 - person Piedone; 14.04.2021

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

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

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

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

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

person krishnakeshan    schedule 18.12.2019

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

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

Подробнее здесь Docker и npm - gyp ERR! не в порядке

person teseo    schedule 06.03.2020