Я фиксирую файл package-lock.json, созданный npm 5?


1397

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

Этот файл должен храниться в системе контроля версий?

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


20
Краткий ответ: да. Один комментарий: при изменении package-lock.json вы можете сделать фиксацию только этого изменения, отдельно от других исходных изменений. С этим git logлегче иметь дело.
Purplejacket

14
Файл не может помочь произвести детерминированную установку, если он не существует.
Алан Х.

4
Зависит от проекта. github.com/npm/npm/issues/20603
Гайус

3
Если вы действительно уверены, что npm уверен, цель состоит в том, чтобы более четко сообщить, что использует проект. Если вы действительно хотите предсказуемость, проигнорируйте этот файл и установите вместо него ваши node_modules (см. .Npmrc и соответствующий конфиг в ответах + комментарии) и используйте его для отслеживания того, что на самом деле меняется, а не того, что ваш менеджер пакетов утверждает, что делает. В конечном итоге: что важнее? Ваш менеджер пакетов или код, который вы используете.
Джиммонт

Ответы:


1617

Да, package-lock.jsonпредназначен для проверки в системе контроля версий. Если вы используете npm 5, вы можете увидеть это в командной строке: created a lockfile as package-lock.json. You should commit this file.Согласно npm help package-lock.json:

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

Этот файл предназначен для фиксации в исходных хранилищах и предназначен для различных целей:

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

  • Предоставьте пользователям возможность «путешествовать во времени» к предыдущим состояниям node_modulesбез фиксации самого каталога.

  • Для облегчения видимости изменений в дереве с помощью читабельных исходных текстов контроля.

  • И оптимизировать процесс установки, позволяя npm пропускать повторные разрешения метаданных для ранее установленных пакетов.

Одним из ключевых моментов package-lock.jsonявляется то, что он не может быть опубликован, и он будет игнорироваться, если будет найден в любом месте, кроме пакета верхнего уровня. Он разделяет формат с npm-shrinkwrap.json (5), который по сути является тем же файлом, но допускает публикацию. Это не рекомендуется, если только не развертывается инструмент CLI или иным образом не используется процесс публикации для создания производственных пакетов.

Если оба package-lock.jsonи npm-shrinkwrap.jsonприсутствуют в корне пакета, package-lock.jsonбудут полностью игнорироваться.


78
В каких проектах на самом деле полезно зафиксировать файл? Весь смысл semver и package.json в том, что обновленные совместимые зависимости не должны быть отмечены.
curiousdannii

45
Ключевое слово - «не должно быть», но на практике люди не следуют полностью. Вот почему вы можете использовать package-lock.json и package.json вместе, чтобы упростить обновление пакетов, но при этом убедитесь, что каждый разработчик и каждое развернутое приложение используют одно и то же дерево зависимостей.
Пану Хорсмалахти

34
@trusktr: Sindre Sorhus рекомендует использовать «Lockfiles для приложений, но не для пакетов».
vine77

23
Другое дело, что package-lock.json игнорируется для публикации в NPM, поэтому, если разработчик использует его для разработчика библиотеки, он сводит к минимуму вероятность того, что он поймает регрессию из обновленной версии зависимости, и, следовательно, пропустит это ошибка на конечных пользователей. По этой причине неиспользование файла блокировки для библиотеки dev повышает вероятность отправки меньшего количества ошибок.
trusktr

129
Лично мне теперь пришлось прибегнуть к добавлению package-lock.jsonсвоих .gitignore... это доставляло мне гораздо больше проблем, чем их решение. Он всегда конфликтует, когда мы сливаем или перебазируем, и когда слияние приводит к package-lock.jsonповреждению на CI-сервере, это просто боль, чтобы продолжать его исправлять.
Стефан З Камиллери

111

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


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

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

7
Я обычно держу установки пакетов отдельно от других работ. Мне никогда не нужно разыгрывать коммит типа «Установленный чай и мокко», потому что я уже знаю, что изменилось.
Кит

3
Любой совет относительно package-lock.jsonфайла при работе в системе SCM со стволами и ветвлениями? Я делаю некоторые изменения в ветке, которую нужно объединить с транком ... Должен ли я теперь (как-то) разрешать конфликты между двумя package-lock.jsonфайлами? Это больно.
kmiklas

3
@ Guerillapresident Насколько я понимаю, вы частично правы. Публикация этого файла в npm не подлежит обсуждению. Вы не можете опубликовать это.
Тим Готье

66

Да, ты должен:

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

npm ciРабочий процесс требует существования таких package-lock.json.


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

  • если package-lock.jsonи package.jsonне синхронизированы
  • если package-lock.jsonотсутствует.

Следовательно, работает npm installлокально, особенно в больших командах с несколькими разработчиками, может привести к большому количеству конфликтов внутри, package-lock.jsonи разработчики решат полностью удалить package-lock.jsonвместо них.

Тем не менее, существует серьезный пример использования для уверенности в том, что зависимости проекта разрешаются многократно и надежно на разных машинах.

От a package-lock.jsonвы получаете именно это: состояние, известное работе.

В прошлом у меня были проекты без package-lock.json/ npm-shrinkwrap.json/ yarn.lockфайлов, сборка которых однажды не удалась, потому что случайная зависимость получила критическое обновление.

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

Если вы хотите добавить новую зависимость, вы все равно запускаете npm install {dependency}. Если вы хотите обновить, используйте либо npm update {dependency}или npm install ${dependendency}@{version}и подтвердите изменения package-lock.json.

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


Чтобы процитировать npm doc :

Настоятельно рекомендуется передать созданную блокировку пакета в систему управления версиями: это позволит всем членам вашей команды, вашим развертываниям, вашей CI / непрерывной интеграции и всем, кто запускает npm install в вашем источнике пакетов, получить точно такое же дерево зависимостей. что вы разрабатывали. Кроме того, различия в этих изменениях понятны человеку и сообщат вам обо всех изменениях, внесенных npm в ваши node_modules, чтобы вы могли заметить, были ли какие-либо транзитивные зависимости обновлены, выведены и т. Д.

И что касается разницы между npm ciпротивnpm install :

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

Примечание: я разместил аналогичный ответ здесь


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

Я обнаружил, что использование фиксированной версии в package.json (без каретки и тильды) намного более чистый вариант. Это спасает меня от whose build would fail one day because a random dependency got a breaking updateпроблем. Хотя это оставляет возможность зависимости ребенка, вызывая ту же проблему.
Ашвани Агарвал

58

Да, лучше всего регистрироваться (ДА, CHECK-IN)

Я согласен, что это вызовет много шума или конфликта при просмотре diff. Но преимущества таковы:

  1. гарантировать точно такую ​​же версию каждого пакета . Эта часть является наиболее важной при построении в разных средах в разное время. Вы можете использовать ^1.2.3в вашем package.json, но , как может у обеспечить каждый раз , когда npm installподберет ту же версию в вашем Dev машине и на сервере сборки, особенно те косвенные пакеты с зависимостями? Хорошо, package-lock.jsonобеспечу это. (С помощью npm ciкоторого устанавливаются пакеты на основе файла блокировки)
  2. это улучшает процесс установки.
  3. это помогает с новой функцией аудита npm audit fix(я думаю, что функция аудита из npm версии 6).

3
Насколько я знаю, никогда не использовать semver (который npm devs не понимает в любом случае) должно привести к тому же поведению, что и наличие файла блокировки, по крайней мере в 99% случаев. Мой собственный опыт показывает, что полувернутые хакерские атаки происходят в основном с первичными пакетами (прямые зависимости, дрянные сборщики данных jquery и т. Д.). Мой личный опыт работы с npm заключался в том, что файлы блокировки всегда были шумом. Я надеюсь, что эта мудрость не изменилась с последними версиями.
Свенд

13
+1 за упоминание npm ci. Люди часто упоминают, что a package-lock.jsonдопускает детерминированную установку пакетов, но почти никогда не упоминают команду, которая облегчает такое поведение! Многие люди, вероятно, ошибочно полагают npm install, что устанавливает именно то, что находится в файле блокировки ...
ahaurat

npm ci отсутствует в npm 5.
dpurrington

Спасибо! Имеет смысл зафиксировать package-lock.json, если вы используете npm ci. Ваша команда / ведущий разработчик может решить, когда обновить. Если все просто произвольно совершают это, в этом нет никакого смысла, и это просто создает шум в вашем репо. Документация NPM должна прояснить это. Я думаю, что большинство разработчиков просто смущены этой функцией.
adampasz

@adampasz на самом деле каждый разработчик может зафиксировать файл блокировки, и после прохождения тестирования и объединения вторая ветвь просто обновляет файл блокировки, если пакеты каким-либо образом меняются (мы не меняем package.json, мы реже сталкиваемся с этой проблемой (
Синь,

38

Я не фиксирую этот файл в своих проектах. В чем смысл ?

  1. Это генерируется
  2. Это является причиной ошибки целостности кода SHA1 в gitlab со сборками gitlab-ci.yml

Хотя это правда, что я никогда не использую ^ в моем package.json для библиотек, потому что у меня был плохой опыт с этим.


11
Я хотел бы, чтобы это можно было более подробно изложить в документации по npm. Было бы полезно составить план того, что конкретно вы теряете, не совершая коммитов package-lock.json. Некоторые репозитории могут не требовать преимуществ, связанных с их наличием, и могут предпочесть не иметь автоматически сгенерированного контента в источнике.
PotatoFarmer

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

6
Вы не можете использовать ^ в вашем package.json, но можете быть уверены, что ваши зависимости его не используют?
neiker

35

Людям, жалующимся на шум при выполнении git diff:

git diff -- . ':(exclude)*package-lock.json' -- . ':(exclude)*yarn.lock'

Я использовал псевдоним:

alias gd="git diff --ignore-all-space --ignore-space-at-eol --ignore-space-change --ignore-blank-lines -- . ':(exclude)*package-lock.json' -- . ':(exclude)*yarn.lock'"

Чтобы игнорировать package-lock.json в diff для всего репозитория (каждый, кто его использует), вы можете добавить это в .gitattributes :

package-lock.json binary
yarn.lock binary

Это приводит к тому, что diff-файлы показывают, что «двоичные файлы a / package-lock.json и b / package-lock.json различаются при каждом изменении файла блокировки пакета. Кроме того, некоторые службы Git (в частности, GitLab, но не GitHub) также исключают эти файлы (не более 10 тыс. строк изменено!) из различий при просмотре онлайн при этом.


1
У меня gd() { git diff --color-words $1 $2 -- :!/yarn.lock :!/package-lock.json; }в .bashrc вместо псевдонима.
apostl3pol

16

Да, вы можете зафиксировать этот файл. Из официальных документов npm :

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

Этот файл предназначен для фиксации в исходных хранилищах [.]


13
Не будет ли установка всегда обновлять node_modules и, следовательно, обновлять package-lock.json?
Тим Готье

2
Нет, вы можете запустить npm ciустановку из пакета package.json
Уильям Хэмпшир

В своем ответе вы должны подчеркнуть, что вы ДОЛЖНЫ использовать npm ci в вашей сборке с непрерывной интеграцией, если у вас есть package-lock.json в
репозитории

6

Отключить пакет-lock.json глобально

введите в своем терминале следующее:

npm config set package-lock false

это действительно работает для меня, как магия


2
это создает ~/.npmrc(по крайней мере, на моих macos) с контентом, package-lock=falseи то же самое можно сделать в любом конкретном проекте рядом node_modules/(например,echo 'package-lock=false' >> .npmrc
jimmont

6
Мне смешно, что это будет негативно. Сообщество npm просто не может смириться с тем, что автоматическая генерация package-lock.json была плохим участием сообщества. Вы не должны делать вещи, которые могут повлиять на процесс команды. это должна была быть опция включения, а не принудительная. сколько людей просто делают "git add *" и даже не замечают этого и не испортили сборки. Если у вас есть какой-либо поток, основанный на слиянии, я знаю, что поток мерзавцев подобен библии для людей, которые его используют, это не сработает. Вы не можете иметь поколение на слияние! Версия npm не работает, пакет: 1.0.0 должен быть детерминированным!
Эрик Твилегар

3
почему за это проголосовали? это явно законный способ отключения функции, которая не работает. И хотя он не отвечает на вопрос как таковой, он ставит вопрос на первый план. т.е. больше не нуждается в ответе. Недурно от меня :)
Superole

Причина, по которой он получает отрицательный голос, заключается в том, что вы просто отключаете функцию.
Раза

5

Да, это стандартная практика для фиксации package-lock.json

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

Плюсы: -

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

Минусы: -

  • Это может привести к тому, что ваши запросы на тягу будут выглядеть ужасно :)

Редактировать: - установка npm не гарантирует, что все в проекте имеют одинаковую версию пакета. npm ci поможет с этим.


4
Минусы исчезли бы, если бы вы использовали npm ciвместо npm install.
k0pernikus


1
«Все в проекте будут использовать одну и ту же версию пакета, все, что вам нужно сделать, это установить npm». Не соответствует действительности, вам нужно использовать «npm ci» вместо этого
reggaeguitar

Спасибо, @reggaeguitar. Обновление моего ответа на это.
Нихил Мохадикар

2

Я использую npm для создания уменьшенных / увеличенных css / js и для создания javascript, необходимого на страницах, обслуживаемых приложением django. В моих приложениях Javascript запускается на странице для создания анимации, иногда выполняет вызовы ajax, работает в рамках VUE и / или работает с CSS. Если package-lock.json имеет некоторый переопределенный контроль над тем, что находится в package.json, то может потребоваться, чтобы была одна версия этого файла. По моему опыту, это либо не влияет на то, что установлено с помощью npm install, либо, если это так, на сегодняшний день не оказало негативного влияния на приложения, которые я развернул, насколько мне известно. Я не использую mongodb или другие подобные приложения, которые традиционно являются тонкими клиентами.

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

Когда npm installон запускается на сервере, он изменяет package-lock.json, и если в файл, записанный репо на сервере, вносятся изменения, при следующем развертывании НЕ БУДЕТ извлекать новые изменения из источника. То есть вы не можете развернуть, потому что pull будет перезаписывать изменения, сделанные в package-lock.json.

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

Если node_modules нет в вашем репо (и не должно быть), то package-lock.json следует игнорировать.

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

jason@localhost:introcart_wagtail$ rm package.json
jason@localhost:introcart_wagtail$ npm install
npm WARN saveError ENOENT: no such file or directory, open '/home/jason/webapps/introcart_devtools/introcart_wagtail/package.json'

и сборка завершается неудачно, однако при установке node_modules или применении npm для сборки js / css жалоб не возникает, если я удаляю package-lock.json

jason@localhost:introcart_wagtail$ rm package-lock.json 
jason@localhost:introcart_wagtail$ npm run dev

> introcart@1.0.0 dev /home/jason/webapps/introcart_devtools/introcart_wagtail
> NODE_ENV=development webpack --progress --colors --watch --mode=development

 10% building 0/1 modules 1 active ...

Просто добавлю, что теперь я добавил свой package-lock.json в свой репозиторий и использую npm ci для моего развертываемого развертывания, которое, как я считаю, удаляет node_modules, и устанавливает все в package-lock.json, не обновляя его. Это позволяет моему партнеру обновлять javascript без необходимости ручного вмешательства в развертывание.
MagicLAMP
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.