Чи потрібно зафіксувати файл package-lock.json, створений npm 5?


1392

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

Чи повинен цей файл зберігатись у контролі джерела?

Я припускаю, що це схоже на, yarn.lockі composer.lockобидва вони повинні зберігатися в контролі джерел.


20
Коротка відповідь: так. Один коментар: коли зміни пакета-lock.json ви можете взяти на себе лише цю зміну, окремо від інших змін джерела. Це git logполегшує справу.
Purplejacket

14
Файл не може допомогти створити детерміновану установку, якщо її не існує.
Алан Х.

4
Залежить від проекту. github.com/npm/npm/isissue/20603
Гаджус

3
Якщо ви справді довіряєте npm впевненості, метою є більш чітке повідомлення про те, що проект використовує. Якщо ви дійсно хочете, щоб передбачуваність ігнорувала цей файл, а замість цього встановіть свої node_modules (див. .Pmrc та пов’язані з цим конфігурації у відповідях та коментарях) і використовуйте це для відстеження того, що насправді змінюється, а не того, що говорить ваш менеджер пакунків. Зрештою: що важливіше? Ваш менеджер пакунків або код, який ви використовуєте.
Джиммонт

Відповіді:


1614

Так, 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буде повністю проігноровано.


77
У яких проектах корисно ввести файл? Вся суть semver та package.json полягає в тому, що оновлені сумісні залежності не потрібно зазначати.
цікаводанні

45
Ключове слово "не повинно бути", але на практиці люди не дотримуються semver ідеально. Ось чому ви можете використовувати пакет-lock.json і package.json разом, щоб полегшити оновлення пакетів, але все одно переконайтесь, що кожен розробник і кожна розгорнута програма використовує одне і те ж дерево залежності.
Пану Хорсмалахті

34
@trusktr: Sindre Sorhus рекомендує використовувати "Lockfiles для додатків, але не для пакетів".
vino77

23
Інша справа, що пакет-lock.json ігнорується для публікації в NPM, тому якщо розробник використовує його для бібліотечного розробника, вони мінімізують шанси на те, що вони знайдуть регрес з оновленої версії залежності, і тому передадуть це помилка кінцевих користувачів. З цієї причини невикористання файлу блокування для бібліотечного розробника збільшує ймовірність доставки менше помилок.
trusktr

128
Особисто мені зараз довелося вдатися до того, щоб додати package-lock.jsonмоє .gitignore... це викликало у мене набагато більше проблем, ніж їх вирішення. Він завжди конфліктує, коли ми зливаємо або ребаюємо, і коли злиття призводить до package-lock.jsonпошкодження на сервері CI, це просто біль, щоб продовжувати його виправляти.
Stefan Z Camilleri

111

Так, це має бути зареєстровано. Я хочу припустити, що він отримує свою унікальну комісію. Ми виявляємо, що це додає багато шуму нашим розсіям.


19
справедливо дискутувати про те, чи слід перевіряти його у сховищі вихідного коду, але публікація цього файлу в npm насправді не готується до дебатів - ви повинні включити або ваш пакунок-lock.json, або ваш файл скорочення у свій реєстр npm. якщо цього не зробити, ваш опублікований пакет буде змінено залежно від залежностей вашого першого покоління. Ви не помітите, що це буде проблемою, поки одна з цих залежностей другого покоління не опублікує переломну зміну, і ваш опублікований пакет не стане таємничо зламаним. цей файл package-lock.json був створений для вирішення цієї проблеми.
партизанський

8
@BetoAveiga від шуму. Я маю на увазі, що у комітетів з 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 щоб будувати додатки як на вашому ІМ, так і на локальній машині розвитку

Робочий 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замість цього.

Однак є вагомий приклад використання для того, щоб можна було довіряти, що залежності проекту вирішуються повторно надійно на різних машинах.

Від 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.


Щоб процитувати НПМ документ :

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

А щодо різниці між npm civsnpm install :

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

Примітка: аналогічну відповідь я розмістив тут


10
Ця відповідь заслуговує на більше кредиту, особливо з використанням npm ci. Використання цього пом'якшує більшість проблем, які виникають у людей із блокуванням пакету.
JamesB

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

58

Так, найкраща практика - це заїзд (ТАК, ЗАВДАННЯ)

Я погоджуюся, що це спричинить багато шуму або конфлікту, коли побачиш різницю. Але переваги:

  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% випадків. Мій власний досвід полягає в тому, що підкачки semver трапляються здебільшого з первинними пакетами (прямі залежності, хитрі jquery datepickers тощо). Мій особистий досвід роботи з npm - це те, що файли блокування навіки шуміли. Я сподіваюся, що ця мудрість не змінилася в останніх версіях.
Свенд

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

npm ci не в npm 5.
dpurrington

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

@adampasz насправді кожен розробник може зробити файл блокування, і як тільки пройти тестування та об'єднати, друга гілка просто оновить файл блокування, якщо якимось чином змінити пакунки (ми не змінюємо пакет.json часто, ми менше стикаємося з цією проблемою (
Сінь

38

Я не ввожу цей файл у своїх проектах. У чому справа ?

  1. Це генерується
  2. Це є причиною помилки цілісності коду SHA1 в gitlab з побудовами gitlab-ci.yml

Хоча це правда, що я ніколи не використовую ^ у своєму пакеті.json для libs, тому що у мене був поганий досвід з ним.


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

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

6
Ви не можете використовувати ^ у своєму пакеті.json, але ви можете бути впевнені, що ваші залежності не використовують його?
Нейкер

35

Для людей, які скаржаться на шум під час роботи git:

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

Це призведе до розбіжностей, які показують, що "Бінарні файли a / package-lock.json та b / package-lock.json відрізняються при зміні файлу блокування пакета. Крім того, деякі служби Git (зокрема GitLab, але не GitHub) також будуть виключати ці файли (не більше 10k рядків змінено!) від відмінних при перегляді в Інтернеті, коли це роблять.


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інсталяцію з пакета-lock.json
Вільям Хемпшир

У Вашій відповіді потрібно наголосити, що ВИ ОБОВ'ЯЗКОВО використовувати npm ci у своїй постійній інтеграції, якщо у вас є пакет-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 просто не може прийняти, що автоматична генерація пакета-lock.json була поганою участю спільноти. не слід робити речі, які можуть впливати на процес роботи команд. це мав би бути варіант включення, а не примусовий. скільки людей просто "git add *" і навіть не помічає цього і накручує нарощування. Якщо у вас є якийсь потік на основі злиття, я знаю, що git flow - це як біблія для людей, які його використовують, це не спрацює. у вас не може бути покоління на злитті! Версія npm зламана, пакет: 1.0.0 має бути детермінованим!
Ерік Твілегар

3
Чому це знищено? це, очевидно, законний спосіб відключення функції, яка не працює. І хоча вона не відповідає на запитання сама по собі, це задає питання. тобто їй більше не потрібно відповідати. Великі пальці від мене :)
Superole

Причина, чому це стає недозволеним, полягає в тому, що ви просто вимикаєте функцію.
Раза

5

Так, це стандартна практика вчинення пакета-lock.json

Основна причина здійснення пакету-lock.json полягає в тому, що всі учасники проекту знаходяться в одній версії пакету.

Плюси: -

  • Якщо ви дотримуєтесь суворої версії та не дозволяєте автоматично оновлювати основні версії, щоб уберегти себе від невідповідних змін у сторонніх пакетах, що здійснюють блокування пакетів.
  • Якщо ви оновлюєте певний пакет, він оновлюється в package-lock.json, і кожен, хто використовує сховище, оновлюється до тієї конкретної версії, коли приймає зміни.

Мінуси: -

  • Це може зробити ваші запити на тягнення виглядати некрасиво :) '

Редагувати: - npm install не переконається, що всі в проекті є в одній версії пакета. npm ci допоможе в цьому.


4
Мінуси зникнуть, якщо ви використовуєте npm ciзамість цього npm install.
k0pernikus


1
"Усі в проекті будуть в одній версії пакета, все, що вам потрібно зробити, це встановити npm" Неправда, вам потрібно використовувати "npm ci" натомість
reggaeguitar

Дякую, @reggaeguitar. Оновлення моєї відповіді на це.
Нікіл Мохадікар

2

Моє використання npm - це генерувати мінімізований / погіршений css / js та генерувати JavaScript, необхідний на сторінках, що обслуговуються програмою django. У моїх програмах Javascript працює на сторінці для створення анімації, інколи виконує дзвінки ajax, працює в рамках VUE та / або працює з css. Якщо пакет-lock.json має деякий переважаючий контроль над тим, що є у package.json, можливо, знадобиться одна версія цього файлу. На мій досвід, це або не впливає на те, що встановлено за допомогою npm install, або, якщо це відбувається, воно досі не впливало негативно на програми, які я розгортаю. Я не використовую mongodb та інші подібні програми, які традиційно є тонкими клієнтами.

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

Коли npm installзапускається на сервері, він змінює package-lock.json, і якщо є зміни у файлі, який записується репо на сервері, наступне розгортання WONT дозволить витягнути нові зміни з походження. Тобто ви не можете розгорнути, тому що витяг замінить зміни, внесені до пакета-lock.json.

Ви навіть не можете перезаписати локально згенерований пакет-lock.json з тим, що знаходиться в репо (reset master hard origin), оскільки npm буде скаржитися коли-небудь, коли ви видасте команду, якщо package-lock.json не відображає те, що знаходиться в node_modules завдяки npm install, тим самим порушуючи розгортання. Тепер, якщо це вказує на те, що в node_modules було встановлено трохи інші версії, це ще раз не викликало у мене проблем.

Якщо node_modules не знаходиться у вашому репортажі (і цього не повинно бути), тоді пакет-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 ...

Додаю лише, що тепер я застосував мій пакет-lock.json до мого сховища, і я використовую npm ci для мого ansible розгортання, який, на мою думку, видаляю node_modules, і встановлює все в package-lock.json, не оновлюючи його. Це дозволяє моєму передньому хлопцеві оновлювати речі JavaScript без необхідності вручну втручатися в розгортання.
MagicLAMP
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.