В чем разница между npm-shrinkwrap.json и package-lock.json?

С выпуском npm@5 он теперь напишет package-lock.json если только npm-shrinkwrap.json уже существует.

Я установил npm@5 глобально через:

npm install npm@5 -g

А теперь, если npm-shrinkwrap.json найден во время:

npm install

предупреждение будет напечатано:

npm WARN read-shrinkwrap This version of npm
is compatible with lockfileVersion@1,
but npm-shrinkwrap.json was generated for lockfileVersion@0.
I'll try to do my best with it!

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

Но почему для него появился новый формат? Что может package-lock.json сделать это npm-shrinkwrap.json не могу?

5 ответов

Решение

Файлы имеют абсолютно одинаковое содержимое, но есть несколько различий в том, как npm обрабатывает их, описанных на сайте docs, а также в файле docs в репозитории npm, который начинается с явного устранения разницы между этими двумя файлами:

  • package-lock.json никогда не публикуется в npm, тогда как npm-shrinkwrap по умолчанию
  • package-lock.json файлы, которых нет в пакете верхнего уровня, игнорируются, но файлы термоусадочной пленки, принадлежащие зависимостям, соблюдаются
  • npm-shrinkwrap.json обратно совместим с версиями npm 2, 3 и 4, тогда как package-lock.json распознается только npm 5+

Вы можете конвертировать существующий package-lock.json для npm-shrinkwrap.json запустив npm shrinkwrap,

Таким образом:

  • Если вы не публикуете свой пакет в npm, выбор между этими двумя файлами не имеет большого значения. Вы можете использовать package-lock.json потому что это значение по умолчанию и его имя более понятно новичкам в npm; в качестве альтернативы, вы можете использовать npm-shrinkwrap.json для обратной совместимости с npm 2-4, если вам трудно убедиться, что все в вашей команде разработчиков используют npm 5+. (Обратите внимание, что npm 5 был выпущен 25 мая 2017 года; обратная совместимость будет становиться все менее и менее важной по мере того, как мы будем получать эту дату, поскольку большинство людей в конечном итоге будут обновляться.)
  • Если вы публикуете свой пакет в npm, у вас есть выбор между:

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


    Официальная точка зрения, описанная (очень кратко) в документации, заключается в том, что вариант 1 следует использовать для библиотек (предположительно, чтобы уменьшить количество дублирования пакетов, вызываемого, когда все зависимости пакета зависят от слегка отличающихся версий одной и той же вторичной зависимости)., но этот вариант 2 может быть целесообразным для исполняемых файлов, которые будут установлены глобально.

Объяснение от NPM Developer:

Идея определенно состоит в том, чтобы package-lock.json был самым последним и лучшим в технологии shrinkwrap, а npm-shrinkwrap.json должен быть зарезервирован для тех немногих драгоценных людей, которые очень заботятся о том, чтобы их библиотеки имели точные node_modules - и для людей, которые хотят, чтобы CI использовал npm@>=2 для установки определенного дерева без необходимости повышения его версии npm.

Новый файл блокировки ("package-lock.json") в основном использует тот же код, тот же формат, что и npm-shrinkwrap (вы можете переименовать их между собой!). Сообщество, похоже, также понимает, что "у него есть файл блокировки", и люди гораздо быстрее реагируют на него. Наконец, наличие нового файла означало, что мы могли бы иметь сравнительно низкий риск обратного компатирования с помощью shrinkwrap без необходимости делать странные вещи, такие как allow-публикации, упомянутые в родительском посте.

Я думаю, что идея заключалась в том, чтобы по умолчанию иметь место - сохранение и сжатие, но избегать возможных проблем с сокращением упаковки, которые не нужны. Таким образом, они просто дали ему новое имя файла, чтобы избежать конфликтов. Кто-то из npm объяснил это более подробно здесь:

https://www.reddit.com/r/javascript/comments/6dgnnq/npm_v500_released_save_by_default_lockfile_better/di3mjuk/

Соответствующая цитата:

npm по умолчанию публикует большинство файлов в вашем исходном каталоге, и люди годами публиковали сокращенные пакеты. Мы не хотели нарушать совместимость. С параметрами --save и shrinkwrap по умолчанию был большой риск того, что они случайно войдут в реестр и распространятся по нему, и в основном предоставят нам возможность обновлять deps и dedupe... null.

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

версии гарантированы только с (так как перезаписывает package-lock.json если есть конфликт с package.json).

npm-shrinkwrap.json версии гарантированы с обоими npm ci и npm install.

Вот как я понял использование для разработчиков приложений (т. Е. Вы создаете приложение, а не библиотеку), и вы хотите сохранить стабильные зависимости:

  • Регистрироваться npm-shrinkwrap.json если вы хотите заблокировать все зависимости (включая дочерние)

  • Регистрироваться package-lock.json если вы хотите заблокировать версии прямых зависимостей, предоставляя больше пространства для маневра при добавлении новых зависимостей.

Таким образом, последнее эквивалентно указанию всех версий прямой зависимости без каких-либо ~/^/>/< в package.json, Чтобы было ясно, с этим вы все равно можете получить разные версии дочерних зависимостей при выполнении чистой проверки. Это потому, что npm всегда пытается получить последние версии, соответствующие вашим спецификациям, что не всегда правильно аннотировано ("обратно совместимо") и, следовательно, может иногда нарушать вашу сборку.

Другие вопросы по тегам