Cli: [ФУНКЦИЯ] Не удаляйте node_modules на npm ci

Созданный на 6 дек. 2019  ·  53Комментарии  ·  Источник: npm/cli

Что почему

Мне бы очень хотелось, чтобы флаг npm ci --keep выполнял инкрементное обновление на нашем сервере сборки, так как это значительно ускорит наши развертывания. Как предлагалось ранее на github и в сообществе . Последнее обновление было 7 октября , когда команда cli проверяла его. Может ли кто-нибудь опубликовать обновление по этому поводу? :-)

Enhancement

Самый полезный комментарий

Вот как бы я хотел, чтобы это работало в идеальном мире:

  • npm install - такое же поведение, как сегодня
  • npm install --from-lockfile - установка из файла блокировки (как ci )
  • npm install --clean - то же поведение, что и npm install но удаление содержимого node_modules
  • npm ci - псевдоним npm install --from-lockfile --clean

Все 53 Комментарий

Это не то, для чего предназначен ci / cleaninstall. Текущее поведение правильное. Вы хотите использовать npm shrinkwrap .

Мы добавили обновление, чтобы избежать удаления node_modules _folder_, но не его _contents_ (как первоначально запрашивалось в этом сообщении). Цель команды npm ci - удалить все, чтобы начать с чистого листа. Если вы хотите сохранить свои старые node_modules, вам понадобится npm i .

Спасибо за ответы! Извините за мой поздний ответ. Я посмотрел на npm shrinkwrap но предназначен ли он для работы на нашем сервере сборки для непрерывной интеграции? При запуске этой команды он переименовывает мой package-lock.json в npm-shrinkwrap.json но что мне тогда следует запускать во время CI? Просто npm install чтобы получить инкрементное обновление? Или мне следует запустить npm ci но это снова удалит все пакеты :-( Я ищу команду, которая выполняет инкрементное обновление, но установит именно то, что находится в нашем package-lock.json

@claudiahdz; Насколько я понимаю, запуск npm install во время CI обновит package-lock.json и это может означать, что запуск той же сборки через пару недель установит другие пакеты. Это неправильно?

Ps Я думал, что npm ci было сокращением от Continuous Integration

Как указано здесь: https://github.com/npm/npm/issues/20104#issuecomment -403321557

Текущее поведение проблематично, если вы используете npm ci внутри контейнера Docker (что довольно распространено для непрерывной интеграции) и у вас есть привязка к node_modules

Это вызывает следующую ошибку:

webpack_1   | npm ERR! path /var/www/project/docker-config/webpack-dev-devmode/node_modules
webpack_1   | npm ERR! code EBUSY
webpack_1   | npm ERR! errno -16
webpack_1   | npm ERR! syscall rmdir
webpack_1   | npm ERR! EBUSY: resource busy or locked, rmdir '/var/www/project/docker-config/webpack-dev-devmode/node_modules'

что затем приводит к остановке контейнера Docker.

Было бы прекрасно иметь флаг --no-delete или если бы npm ci мог удалить _contents_ из node_modules но не сам каталог.

ci = чистая установка

Это ожидаемо. Почему бы вам не использовать обычный npm i с файлом блокировки?

Было бы прекрасно иметь флаг --no-delete или если бы npm ci мог удалять содержимое node_modules, но не сам каталог.

rm -rf node_modules/* && npm i

ci = чистая установка

Это ожидаемо. Почему бы вам не использовать обычный npm i с файлом блокировки?

... потому что: https://docs.npmjs.com/cli/ci.html

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

Более быстрая установка и подход с чистого листа делают его идеальным для сред CI, таких как та, которую я упомянул выше.

rm -rf node_modules / * && npm i

Это то, что я делаю сейчас, но см. Выше желание использовать npm ci

Мне кажется разумным подать RFC с просьбой указать флаг конфигурации, который заставляет npm ci удалять содержимое node_modules а не сам каталог. Это также проблема для меня, поскольку я настроил Dropbox на выборочное игнорирование директории node_modules , но если я удалю ее, эта выборочная настройка исчезнет, ​​и в следующий раз node_modules создается, синхронизируется.

Мне кажется разумным подать RFC с просьбой указать флаг конфигурации, который заставляет npm ci удалять _contents_ из node_modules а не сам каталог. Это также проблема для меня, поскольку я настроил Dropbox на выборочное игнорирование директории node_modules , но если я удалю ее, эта выборочная настройка исчезнет, ​​и в следующий раз node_modules создается, синхронизируется.

Разве это не описанная еще одна проблема, позволяющая npm создавать файлы, игнорирующие каталог (для OSX Spotlight и других)? Я думаю, что были и другие, кому нужна эта функция.

ci = чистая установка

Это ожидаемо. Почему бы вам не использовать обычный npm i с файлом блокировки?

npm i будет отличным вариантом, но только если он не изменит файл блокировки. Я видел, как package-lock.json обновлялся во время npm i или этого не должно произойти?

Я поддерживаю эту функцию. Как указано, npm i изменяет package-lock.json. Флаг был бы идеальным решением.

то же самое, флаг было бы здорово

Я поддерживаю эту функцию. Как указано, npm i изменяет package-lock.json. Флаг был бы идеальным решением.

Почему бы тогда не добавить флаг для npm i ? Потому что в моем понимании это не имело бы большого смысла для ci = clean install .

Какая часть «чистой установки» несовместима с сохранением нетронутого родительского каталога node_modules/ (при выполнении чистой установки фактического содержимого)?

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

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

npm ci специально предназначен для использования в автоматизированных средах, во многих случаях это означает установку на основе Docker.

Поведение при удалении каталога node_module/ вызывает проблемы при установке на основе Docker по причинам, упомянутым в этой теме.

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

Я поддерживаю эту функцию. Как указано, npm i изменяет package-lock.json. Флаг был бы идеальным решением.

Почему бы тогда не добавить флаг для npm i ? Потому что в моем понимании это не имело бы большого смысла для ci = clean install .

Я должен задать этот вопрос, есть ли у них другие различия между npm install и npm ci если нет, то почему оба варианта недоступны в npm install возможно, ci потребности чтобы стать каким-то псевдонимом вроде npm install --no-update-package-lock --clean-node-modules

Поведение при удалении каталога node_module/ вызывает проблемы в настройке на основе Docker по причинам, упомянутым в этой теме.

На мой взгляд, это должно произойти только один раз при построении образа. После этого при разработке следует использовать npm i .

возможно, ci должен стать псевдонимом, например npm install --no-update-package-lock --clean-node-modules

Лично для меня это имеет больше смысла, дополнительные флаги для обычной команды npm i .

Мне безразлично, что, и, честно говоря, слишком много n00b с js land, чтобы иметь конкретный аргумент, что это должно быть ci , все, что я знаю, это то, что он не должен обновлять package-lock.json и не следует удалять node_modules

npm ci не обновляет файл блокировки, он устанавливается из файла блокировки. Это было введено для выполнения чистой установки, потому что до этого людям было рекомендовано rm -rf node_modules и снова запустить npm i . И, черт возьми, люди хотели, чтобы он не изменял файл блокировки, а устанавливал из него.

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

См. Https://blog.npmjs.org/post/171556855892/introduction-npm-ci-for-faster-more-reliable

Он охватывает конкретный вариант использования.

Для других случаев использования мы должны добавить новые флаги в npm i с помощью которых мы также можем эмулировать npm ci что является более гибким и лучшим решением, чем флаги для npm ci которые по-прежнему должны охватывать только текущий вариант использования imho. То, что здесь запрашивают пользователи, немного похоже на yarn install --frozen-lockfile или yarn --frozen-lockfile .

В противном случае флаги распространяются на npm ci , npm i и т.д., что немного усложняет задачу (документация, код, ...). По крайней мере, я так думаю. Скажем так, npm i t имеют более мощные и гибкие способы настройки его поведения.

Для других случаев использования мы должны добавить новые флаги в npm i, с помощью которых мы также можем эмулировать npm ci, что является более гибким и лучшим решением, чем флаги для npm ci, которые по-прежнему должны охватывать только текущий вариант использования imho. То, что здесь запрашивают пользователи, немного похоже на yarn install --frozen-lockfile или yarn --frozen-lockfile.

Я был бы очень рад, если бы эта функция была добавлена ​​в npm i . Стоит ли обновить исходный пост?

npm ci не обновляет файл блокировки, он устанавливается из файла блокировки. Это было введено для выполнения чистой установки, потому что до этого людям было рекомендовано rm -rf node_modules и снова запустить npm i . И, черт возьми, люди хотели, чтобы он не изменял файл блокировки, а устанавливал из него.

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

См. Https://blog.npmjs.org/post/171556855892/introduction-npm-ci-for-faster-more-reliable

Он охватывает конкретный вариант использования.

Для других случаев использования мы должны добавить новые флаги в npm i с помощью которых мы также можем эмулировать npm ci что является более гибким и лучшим решением, чем флаги для npm ci которые по-прежнему должны охватывать только текущий вариант использования imho. То, что здесь запрашивают пользователи, немного похоже на yarn install --frozen-lockfile или yarn --frozen-lockfile .

Как rm -rf node_modules/* не квалифицируются как "уборка"? Запрошенная здесь функция очень похожа на ту, что присутствует в npm ci. На мой взгляд, имеет смысл добавить флаг в npm ci, чтобы он использовал rm -rf node_modules/* вместо rm -rf node_modules вместо импорта всего поведения npm ci в npm i.

Кстати, этой проблеме следует уделять больше внимания, и сопровождающие должны высказать свое мнение и планы по этому поводу, использование докеров в основном всегда используется в CI (непрерывная интеграция), которая является одним из основных вариантов использования npm ci!

Пожалуйста, откройте RFC для этого изменения, а не для проблемы в этом репо.

Чтобы избежать путаницы, я бы переименовал эту проблему как «пусто вместо удаления каталога node_modules в npm CI».

Я никогда не намеревался удалять папку node_modules или только ее содержимое. Это всегда было сделано для того, чтобы сохранить содержимое node_modules но убедиться, что оно обновлено и синхронизировано с package-lock.json . Итак, инкрементное обновление, которое соответствует package-lock.json .

Возможно, я ошибаюсь, но я чувствую, что здесь есть две проблемы. Может быть, кто-то может начать другую проблему или RFC об удалении только содержимого node_modules вместо полного удаления папки? Или я что-то упускаю?

@Zenuka - вся причина, по которой npm CI работает быстро и существует, заключается в том, что он игнорирует существующий каталог node_modules, поэтому маловероятно, что это изменится.

В нашем случае, я думаю, было бы быстрее просто проверить, обновлена ​​ли папка nodes_modules . И если это не так, обновляйте только те пакеты, которые должны быть обновлены (например, npm i ). У меня есть выделенная виртуальная машина, работающая как агенты сборки, поэтому запускаем сборку и сохраняем папку nodes_modules и все ее содержимое. должно быть быстрее, чем удаление всего и повторная установка. Мы запускаем нашу сборку и тесты на предмет изменений кода намного больше, чем изменений в наших package.json или package-lock.json .

В нашем случае, я думаю, было бы быстрее просто проверить, обновлена ​​ли папка nodes_modules .

Что ж, это (расчет дерева пакетов) занимает больше всего времени. Эта проверка сделает npm ci очень медленным.

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

Вероятно, нет, поэтому был введен npm ci который пропускает то, что делает npm i (проверьте дерево пакетов).

@Zenuka npm install уже является самым быстрым способом сделать то, что вы хотите. npm ci имеет только одну цель: сделать это быстрее, удалив node_modules, чтобы не вычислять разницу.

Наверное, нет, поэтому был введен npm ci, который пропускает то, что делает npm i (проверьте дерево пакетов).

Я тестировал это только на своей машине (что, конечно, не очень хорошо), но запуск npm install в обновленной папке node_modules завершается в течение 10 секунд. Запуск npm ci занимает минуты. Ожидали бы вы других результатов?

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

Проверка того, что содержимое package-lock.json действительно присутствует, выполняется очень быстро даже в Windows. См. Https://github.com/fuzzykiller/verify-node-modules.

Проверка того, что в node_modules больше ничего нет, определенно займет немного больше времени, но, вероятно, все же меньше секунды.

На этом основании можно легко создать инкрементную версию npm ci . В конце концов, дерево уже рассчитано и сохранено в package-lock.json .

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

только мои 2 цента, я лично переключил нашу инфра на npm ci как меня тоже тошнит от развертывания старого тега npm i не будет придерживаться файла блокировки ... так что если это серьезно такая большая проблема, чтобы добавить флаг на уровне npm ci (который я получаю .. его clean install он делает то, что он сказал), тогда npm i REALLLLLYLYY нуждается в этом флаге. но я помню, как исследовал это, и была также ветка проблемы на npm i которая была примерно двухлетней давности (и все еще открыта), где команда npm предлагала людям использовать npm ci lol ... это Это своего рода причина, по которой люди отказались от npm в прошлом и просто перешли на пряжу.

снова просто еще одна точка зрения разработчиков

Я проголосовал за добавление возможности сохранять модули: heavy_plus_sign:.

+1 здесь - как сказали @phyzical и @fuzzykiller , нет " npm install и npm ci которое будет СОХРАНИТЬ node_modules, но при этом будет уважать package-lock.json и работать быстрее.
Просто запустите как можно быстрее - найдите зависимости от package-lock, которые уже существуют в node_modules, а затем установите все остальное, что отсутствует ... без обновлений, без удаления.

Лично мне все равно, какой именно ( install или ci ) будет иметь это, но все это звучит так, как будто npm install должны иметь только флаги для всего и npm ci не обязательно должна быть отдельной командой.

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

Первоначальное поведение, которое многие люди хотели для npm install заключалось в том, чтобы смотреть на package-lock.json вместо package.json . Нам нужен флаг на npm install чтобы включить такое поведение. Вместо этого мы получили npm ci , потому что:

package.json описывает необходимые зависимости вашего проекта. Если текущий файл блокировки не может удовлетворить их, файл блокировки должен уступить. Цель файла блокировки - создать повторяемую установку на разных машинах, а не устаревать package.json.

Так хорошо. npm install - неподходящее место для этой опции, npm ci - подходящее место. За исключением того, что npm ci добавляет дополнительные поведения (очистка папки node_modules ), которые не позволяют ему быть полезным решением исходной проблемы. Причина, по которой сейчас не может быть флага на npm ci заключается в следующем:

ci = чистая установка

Это ожидаемо. Почему бы вам не использовать обычный npm i с файлом блокировки?

Что ... нормально. Мне все равно, где добавить флаг. Я не заинтересован в философии, лежащей в основе интерфейса. Но можно ли добавить флаг где-нибудь ?

Черт возьми, я бы не стал возражать, даже если бы люди захотели полностью отдельную третью команду, мне все равно. Единственное, что меня волнует, это то, что через 3 года после того, как начался этот разговор об уважении package-lock.json для обычных установок, все еще нет способа добиться того поведения, о котором мы изначально просили.

На моем рабочем месте мы видели ошибки, связанные с обновлениями второстепенных и исправленных версий пакетов. Мы действительно хотим искать эти ошибки только во время целенаправленных обновлений пакетов, мы не хотим, чтобы наши среды разработки использовали версии пакетов, отличные от наших производственных сред. Последовательность там очень важна. Независимо от того, что кто-то хочет называть это или где угодно, нам нужен быстрый способ получения пакетов из файла блокировки, который также не потребует от нас сидения через node-gyp сборок для уже установленных модулей каждый раз, когда мы запустите команду.

Вот как бы я хотел, чтобы это работало в идеальном мире:

  • npm install - такое же поведение, как сегодня
  • npm install --from-lockfile - установка из файла блокировки (как ci )
  • npm install --clean - то же поведение, что и npm install но удаление содержимого node_modules
  • npm ci - псевдоним npm install --from-lockfile --clean

@jdussouillez Это именно то, что должно произойти. Очень хорошо сказано! Я бы хотел, чтобы это решение было реализовано.

Постоянно неприятно сталкиваться с этой проблемой, когда нам приходится выбирать между скоростью и согласованностью конвейера CI. Я сталкивался с этим 3 или 4 раза по разным причинам только за последние 2 месяца.

Эта функция отлично подходит для Azure Pipelines и других облачных архитектур.

https://docs.microsoft.com/en-us/azure/devops/pipelines/release/caching?view=azure-devops#tip

Поскольку npm ci удаляет папку node_modules, чтобы обеспечить использование согласованного, повторяемого набора модулей, вам следует избегать кеширования node_modules при вызове npm ci.

Заключение : как упоминал npm ci больше не удаляет саму папку node_nodules , а только ее содержимое (см. Https://github.com/npm /libcipm/blob/latest/CHANGELOG.md#407-2019-10-09). Это было отправлено в [email protected] обратно 21 июля (см. Https://github.com/npm/cli/blob/v6/CHANGELOG.md#6147-2020-07-21), и мы поддерживали тот же опыт в npm@7 .

Если у вас есть отдельная проблема с npm ci или любой другой командой, используйте один из наших шаблонов задач, чтобы сообщить об ошибке: https://github.com/npm/cli/issues/new/choose


Боковые примечания ...

@jdussouillez ценит отзывы; Что касается установки непосредственно из файла блокировки - вы можете сделать это сегодня с флагом --package-lock-only (например, npm install --package-lock-only ). Что касается добавления флага --clean к install , я не чувствую, что это добавляет большого значения, но я могу ошибаться. Если вы уверены в этом, мы будем рады, если вы отправите RFC по адресу https://github.com/npm/rfcs.

Комментарий, сделанный @claudiahdz почти год назад, похоже, связан с тем, что поведение npm ci заключается в удалении содержимого node_modules , а не самой папки. Это удобно при установке его в контейнер докеров (например), но все равно не меняет конечный результат - npm ci загрузит все зависимости с нуля.

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

То , что я понял из оригинального вопроса, является необходимость иметь возможность , которая получает текущее состояние node_modules папки, и package-lock.json файла и загружает только необходимые пакеты , чтобы получить node_modules версий для соответствия package-lock.json . Так что это будет намного быстрее, чем скачивать все каждый раз, с тем же чистым результатом в конце.

Разве не это уже всегда делает npm install ?

Разве не это уже всегда делает npm install ?

НАСКОЛЬКО МНЕ ИЗВЕСТНО -
npm install разрешит все зависимости в соответствии с файлом package.json (игнорируя package-lock.json ), сравнит с тем, что в настоящее время находится в папке node_modules , и загрузит зависимости, которые необходимо загрузить для соответствия требованиям. Он также обновит package-lock.json соответственно.

Он определенно не игнорирует файл блокировки - он просто принимает во внимание существующее дерево, чего npm ci нет.

Вы правы, мне очень жаль.
Я неправильно вспомнил (может быть, так было раньше?). Только что провел небольшое тестирование с простым деревом депов, и когда присутствует файл package-lock.json , npm i устанавливает именно те версии, которые он указывает, и ничего не меняет. Это было именно то поведение, которое я искал, так что я им доволен. 👍
Прошу прощения за публикацию по закрытому вопросу.

Моя первоначальная просьба была действительно тем, что описывает ATGardner:

То , что я понял из оригинального вопроса, является необходимость иметь возможность , которая получает текущее состояние node_modules папки, и package-lock.json файла и загружает только необходимые пакеты , чтобы получить node_modules версий для соответствия package-lock.json . Так что это будет намного быстрее, чем скачивать все каждый раз, с тем же чистым результатом в конце.

Мой опыт работы с npm install показывает, что он иногда обновляет файл package-lock.json . Я снова протестировал это сегодня утром с репозиторием, который я не обновлял некоторое время, и запустил git pull и npm i . На этот раз он фактически не обновил никаких версий, просто добавил некоторые зависимости и дополнительные пакеты.
image
К сожалению, это частный репозиторий, но, может быть, кто-то другой в качестве воспроизводимого публичного репозитория? Если есть несколько коммитов и переключение между ними приводит к тому, что npm install обновляет package-lock.json ?

Я понимаю, что может возникнуть некоторая ошибка пользователя, если не выполнить package-lock.json при обновлении package.json но мои коллеги знают, что они также должны обновить package-lock.json . Я займусь этим.

Я не мог получить свой простой пример, чтобы npm i изменил файл package-lock.json . Но я попробую еще немного.

Если npm i всегда заканчивает загрузку тех же самых версий, которые указаны в package-lock.json , сохраняя как можно больше из текущего node_modules , зачем мне когда-либо нужно запускать npm ci ? какая польза от удаления всего перед повторной загрузкой?

Я еще раз прошу прощения за то, что это не место для этой дискуссии. Есть ли что-нибудь более предпочтительное?

Я все еще не понимаю. Если состояние node_modules после запуска npm i точности совпадает с package-lock.json , а состояние node_modules после запуска npm ci имеет то же самое конечный результат - почти во всех сценариях, если компьютер, на котором вы строите, уже имеет некоторые / большинство зависимостей в папке, не будет ли npm i быстрее? Он просто не будет загружать то, что уже есть локально и соответствует требуемой версии.

Почему мне лучше удалить и скачать все с нуля?

Нет, npm ci по-прежнему быстрее, так как он не проверяет deptree снова, некоторые консольные выходные данные не выполняются.

Почему мне лучше удалить и скачать все с нуля?

Чтобы предотвратить проблемы, ci предназначен для определенных сред, таких как развертывания.
Я думаю, что в документах уже упоминаются различия.

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

См. Также https://blog.npmjs.org/post/171556855892/introduction-npm-ci-for-faster-more-reliable

npm ci все еще быстрее.

Таким образом, при использовании npm i время, необходимое для чтения текущего node_modules и определения пакетов, которые следует загрузить, значительно больше, чем время, необходимое для фактической загрузки всех пакетов из npm. серверы? Я бы хотел увидеть настоящий эксперимент, который его измеряет.

И я тоже не понимаю этот абзац -

npm ci bypasses a package’s package.json to install modules from a package’s lockfile. This ensures reproducible builds—you are getting exactly what you expect on every install.

Разве мы не пришли к выводу, что при запуске npm i используются точные версии в файле package-lock.json , а состояние node_modules после запуска идентично состоянию, в котором он будет быть после запуска npm ci ? Так что сборки будут такими же воспроизводимыми.

ОБНОВИТЬ:

Я сделал следующий тест -
Я создал новый проект create-react-app . После завершения инициализации у него был package.json с 7 прямыми зависимостями и package-lock.json , содержащий пакеты 1982 года.
В этом состоянии ( node_modules содержит все зависимости) - запуск npm i занимает

real    0m2.548s
user    0m2.659s
sys     0m0.182s

Когда я удалил одну папку пакета ( node_modules/babel-eslint ), а затем снова запустил npm i , потребовалось

real    0m3.295s
user    0m3.543s
sys     0m0.434s

чтобы повторно загрузить недостающую зависимость

Когда я удалил всю папку node_moduels и снова запустил npm i , потребовалось

real    0m16.701s
user    0m19.251s
sys     0m10.379s

Когда я запустил npm ci , потребовалось

real    0m20.997s
user    0m23.844s
sys     0m14.857s

Это не сильно отличалось, когда я пытался удалить один пакет или даже удалить всю папку node_modules вручную перед вызовом. Это неудивительно, поскольку npm ci node_modules любом случае начинается с удаления содержимого

После каждого запуска я запускал diff -q -r node_modules_orig/ node_modules/ чтобы убедиться, что результат идентичен исходным зависимостям. Так было всегда.

Итак, в заключение - похоже, что использование npm ci на моей машине занимает ~ 21 секунду, независимо от текущего состояния node_modules . Использование npm i в недавно клонированном проекте (без node_modules ) занимает ~ 18 секунд, а запуск его в проекте, в котором нет измененных зависимостей (текущий node_modules соответствует требуемым зависимостям. ) занимает ~ 3 секунды.

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

npm ci предпочтительнее, когда вам нужно _ точно_ то, что находится в package-lock.json и ничего кроме. npm i не гарантирует, что он установит именно то, что находится в package-lock.json . Это сделано намеренно. Хотя package-lock.json является входом для npm i , он также является выходом.

Я считаю, что осталось всего несколько случаев, когда npm i установит что-то другое (и, таким образом, изменит package-lock.json ), например, версии пакетов, которые были мягко удалены.

Когда был впервые представлен npm ci , npm i либо полностью игнорировал package-lock.json либо, по крайней мере, был намного более проактивным при установке разных версий.

В любом случае это не имеет значения. npm ci работает только тогда, когда папка node_modules еще не существует. В противном случае это будет недопустимо медленно, особенно в Windows. Итак, npm i просто нужен флаг, который _гарантирует_, что он не изменит package-lock.json и установит именно то, что находится внутри package-lock.json .

Не вижу смысла дальше обсуждать, почему и как. Либо мы получим, либо нет. Как есть, npm ci отстой.

/Обновить:
Вот репо, где запуск npm i изменит package-lock.json : https://github.com/fuzzykiller/npm-install-demo

Хотя изменения носят чисто технический характер, они по-прежнему неприемлемы.

Просто чтобы быстро повторить:

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

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

  • npm install --package-lock-only описывается в документации :

    Аргумент --package-lock-only обновляет только package-lock.json, вместо проверки node_modules и загрузки зависимостей.

    Это не кажется полезным ни для одного из описанных выше сценариев.

Что люди просили в течение последних 3 лет:

  1. Команда (где угодно), которая игнорирует package.json и _only_ уважает package-lock.json как окончательный источник того, какие пакеты будут установлены.

  2. Это не приведет к удалению всего содержимого node_modules и повторной загрузке всего с нуля.

Насколько я могу видеть как из документации, так и из локального тестирования, npm install удовлетворяет пункту 2, но не 1. npm ci удовлетворяет пункту 1, но не 2. npm install --package-lock-only удовлетворяет ни одному этих требований.

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


Изменить: чтобы продолжить пример @fuzzykiller , это не просто обновление package-lock.json . Это было бы неприятно, но не сломало бы ни одну из моих сборок. Но если в package.json есть нечеткие зависимости, перечисленные где-либо, и выпущена версия этих зависимостей с исправлением ошибок, они будут изменены, когда я запустил npm install на новой машине. Внезапно у меня установились отличия между двумя машинами. Мы столкнулись с ошибками в моей компании именно из-за такого поведения, дело не только в том, что package-lock.json нужно снова проверить в Git.

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

Для решения этой проблемы может быть где угодно флажок. Это может быть npm install --from-lockfile . Это может быть npm ci --preserve-existing . Но сейчас кажется, что мы находимся в кругу, где любой, кто просит добавить флаг к npm install получает указание на npm ci в качестве решения, а любой, кто запрашивает флаг на npm ci указывает на npm install в качестве решения. Эта проблема была закрыта, указав на npm install --package-lock-only , но этот флаг почти противоположен тому, что люди просят. Он не уважает package-lock.json как авторитетный источник, а также не обновляет и не устанавливает какие-либо зависимости в папке node_modules :)

Этот вопрос следует открыть повторно.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги