Czy mogę zatwierdzić plik package-lock.json utworzony przez npm 5?


1391

npm 5 został wydany dzisiaj, a jedną z nowych funkcji są deterministyczne instalacje wraz z tworzeniem package-lock.jsonpliku.

Czy ten plik powinien być pod kontrolą źródła?

Zakładam, że jest podobny yarn.locki composer.lockoba powinny być pod kontrolą źródła.


20
Krótka odpowiedź: tak. Jeden komentarz: kiedy zmienia się pakiet-lock.json, możesz zatwierdzić właśnie tę zmianę, niezależnie od innych zmian źródłowych. Ułatwia to git logobsługę.
Purplejacket

14
Plik nie może pomóc w utworzeniu deterministycznej instalacji, jeśli nie istnieje.
Alan H.

4
Zależy od projektu. github.com/npm/npm/issues/20603
Gajus

3
Jeśli naprawdę ufasz npm, celem jest wyraźniejsze zgłoszenie, z czego korzysta projekt. Jeśli naprawdę chcesz przewidywalności, zignoruj ​​ten plik i zamiast tego zainstaluj moduły node_modules (zobacz .npmrc i pokrewną konfigurację w odpowiedziach + komentarzach) i użyj tego do śledzenia tego, co się faktycznie zmienia, a nie tego, co robi twój menedżer pakietów. Ostatecznie: co jest ważniejsze? Twój menedżer pakietów lub kod, którego używasz.
Jimmont

Odpowiedzi:


1613

Tak, package-lock.jsonjest przeznaczony do kontroli źródła. Jeśli używasz npm 5, możesz zobaczyć to w wierszu poleceń: created a lockfile as package-lock.json. You should commit this file.Zgodnie z npm help package-lock.json:

package-lock.jsonjest generowany automatycznie dla wszystkich operacji, w których npm modyfikuje albo node_modulesdrzewo, albo package.json. Opisuje dokładnie wygenerowane drzewo, dzięki czemu kolejne instalacje mogą generować identyczne drzewa, niezależnie od pośrednich aktualizacji zależności.

Ten plik ma być przeznaczony do repozytoriów źródłowych i służy do różnych celów:

  • Opisz pojedynczą reprezentację drzewa zależności, tak aby członkowie zespołu, wdrożenia i ciągła integracja gwarantowali zainstalowanie dokładnie tych samych zależności.

  • Zapewnij użytkownikom możliwość „podróży w czasie” do poprzednich stanów node_modulesbez konieczności zatwierdzania samego katalogu.

  • Aby ułatwić lepszą widoczność zmian drzewa dzięki czytelnym różnicom kontroli źródła.

  • I zoptymalizuj proces instalacji, pozwalając npm na pomijanie powtarzających się rozdzielczości metadanych dla wcześniej zainstalowanych pakietów.

Jednym z kluczowych szczegółów package-lock.jsonjest to, że nie można go opublikować i zostanie zignorowany, jeśli zostanie znaleziony w innym miejscu niż pakiet najwyższego poziomu. Dzieli format z npm-shrinkwrap.json (5), który jest zasadniczo tym samym plikiem, ale umożliwia publikację. Nie jest to zalecane, chyba że wdrażasz narzędzie CLI lub w inny sposób używasz procesu publikacji do produkcji pakietów produkcyjnych.

Jeśli oba package-lock.jsoni npm-shrinkwrap.jsonsą obecne w głównym pakietu, package-lock.jsonbędą całkowicie ignorowane.


77
W jakich projektach rzeczywiście jest pomocne zatwierdzenie pliku? Cały sens semver i package.json polega na tym, że zaktualizowane kompatybilne zależności nie powinny być odnotowywane.
curiousdannii

45
Kluczowym słowem jest „nie powinno być” - ale w praktyce ludzie nie przestrzegają semver doskonale. Dlatego możesz używać package-lock.json i package.json razem, aby ułatwić aktualizację pakietów, ale nadal upewniając się, że każdy programista i każda wdrożona aplikacja korzysta z tego samego drzewa zależności.
Panu Horsmalahti

34
@trusktr: Sindre Sorhus zaleca używanie „plików blokujących dla aplikacji, ale nie dla pakietów”.
vine77

23
Inną rzeczą jest to, że pakiet-lock.json jest ignorowany przy publikowaniu w NPM, więc jeśli programista użyje go dla dewelopera biblioteki, to minimalizują szansę, że złapią regresję ze zaktualizowanej wersji zależności, a zatem przekażą to błąd dla użytkowników końcowych. Z tego powodu nieużywanie pliku blokady do tworzenia bibliotek zwiększa szansę na dostarczenie mniej błędów.
trusktr

128
Osobiście musiałem teraz uciekać się do dodawania package-lock.jsondo mojego .gitignore... powodowało to o wiele więcej problemów niż ich rozwiązywanie. Zawsze powoduje konflikt, gdy łączymy lub zmieniamy bazę, a gdy scalanie powoduje package-lock.jsonuszkodzenie na serwerze CI, to jest ból, że trzeba go nadal naprawiać.
Stefan Z Camilleri

111

Tak, jest przeznaczony do zameldowania. Chcę zasugerować, że otrzyma swoje własne unikalne zatwierdzenie. Stwierdzamy, że powoduje to duży hałas w naszych różnicach.


19
sprawiedliwie jest debatować, czy powinien być zapisany w repozytorium kodu źródłowego, ale opublikowanie tego pliku w npm nie jest tak naprawdę do debaty - musisz dołączyć plik package-lock.json lub plik shrinkwrap do rejestru npm. jeśli tego nie zrobisz, opublikowany pakiet będzie podlegał przypiętym zmianom zależności zależności 1. generacji. nie zauważysz, że jest to problem, dopóki jedna z zależności 2. i 2. generacji nie opublikuje przełomowej zmiany, a opublikowany pakiet ulegnie tajemniczemu uszkodzeniu. ten plik package-lock.json został stworzony w celu rozwiązania tego problemu.
partyzantka

8
@BetoAveiga przez hałas Mam na myśli, że commits z pakiet-lock.json mogą mieć tyle wierszy wersji pakietu węzłów, że wszelkie inne prace w tym zatwierdzeniu zostają ukryte.
xer0x

7
Zazwyczaj instalacje pakietów trzymam oddzielnie od innych prac. Nigdy nie muszę różnicować zatwierdzenia typu „Zainstalowane Chai i Mokka”, ponieważ już wiem, co się zmieniło.
Keith,

3
Wszelkie porady dotyczące package-lock.jsonpliku podczas pracy w systemie SCM z pniami i rozgałęzieniami? Wprowadzam pewne zmiany w gałęzi, które muszą zostać scalone do pnia ... czy teraz muszę (jakoś) rozwiązać konflikty między dwoma package-lock.jsonplikami? To jest bolesne.
kmiklas

3
@ guerillapresident Jak rozumiem, masz częściowo rację. Opublikowanie tego pliku w npm nie jest przedmiotem dyskusji. Nie możesz tego opublikować.
Tim Gautier,

66

Tak, powinieneś:

  1. popełnić package-lock.json.
  2. używaj npm cizamiastnpm install podczas budowania aplikacji zarówno na CI, jak i na lokalnym komputerze programistycznym

Przepływ npm cipracy wymaga istnienia pliku package-lock.json.


Dużym minusem npm installpolecenia jest jego nieoczekiwane zachowanie, które może mutować package-lock.json, podczas gdy npm ciużywa tylko wersji określonych w pliku blokującym i powoduje błąd

  • jeśli package-lock.jsoni nie package.jsonsą zsynchronizowane
  • jeśli package-lock.jsonbrakuje a.

Dlatego działając npm installlokalnie, szczególnie. w większych zespołach z wieloma programistami może prowadzić do wielu konfliktów wewnątrz package-lock.jsoni deweloperów, aby zdecydować się na całkowite ich usunięcie package-lock.json.

Istnieje jednak mocny przypadek, że można ufać, że zależności projektu są rozwiązywane powtarzalnie w niezawodny sposób na różnych komputerach.

Od A package-lock.jsondostaniesz dokładnie to: stan znany na rynek pracy.

W przeszłości miałem projekty bez plików package-lock.json/ npm-shrinkwrap.json/ yarn.lock, których kompilacja by się nie udała pewnego dnia, ponieważ losowa zależność otrzymała przełomową aktualizację.

Te problemy są trudne do rozwiązania, ponieważ czasami trzeba odgadnąć, jaka była ostatnia działająca wersja.

Jeśli chcesz dodać nową zależność, nadal działa npm install {dependency}. Jeśli chcesz zaktualizować, użyj albo npm update {dependency}albo npm install ${dependendency}@{version}i zatwierdź zmienioną package-lock.json.

Jeśli aktualizacja się nie powiedzie, możesz powrócić do ostatniego znanego działania package-lock.json.


Aby zacytować npm doc :

Zdecydowanie zaleca się, aby wygenerowaną blokadę pakietu przypisać do kontroli źródła: pozwoli to każdemu innemu zespołowi, Waszym wdrożeniom, CI / ciągłej integracji oraz każdemu innemu, kto uruchomi npm instalację w twoim źródle pakietów, aby uzyskać dokładnie to samo drzewo zależności nad którym pracowałeś. Dodatkowo różnice od tych zmian są czytelne dla człowieka i poinformują cię o wszelkich zmianach dokonanych przez npm w twoim module_węzła, dzięki czemu możesz zauważyć, czy jakieś zależności przechodnie zostały zaktualizowane, podniesione itp.

I w odniesieniu do różnicy między npm civsnpm install :

  • Projekt musi mieć istniejący pakiet-lock.json lub npm-shrinkwrap.json.
  • Jeśli zależności w blokadzie pakietu nie pasują do zależności w pakiecie.json, npm cizakończy działanie z błędem, zamiast aktualizować blokadę pakietu.
  • npm ci można instalować tylko całe projekty na raz: za pomocą tego polecenia nie można dodawać indywidualnych zależności.
  • Jeśli a node_modulesjest już obecny, zostanie automatycznie usunięty przed npm cirozpoczęciem instalacji.
  • Nigdy nie napisze do package.jsonżadnej z blokad pakietów: instalacje są zasadniczo zawieszone.

Uwaga: podałem podobną odpowiedź tutaj


10
Ta odpowiedź zasługuje na większe uznanie, szczególnie przy użyciu npm ci. Korzystanie z tego rozwiązania ogranicza większość problemów związanych z blokadą pakietów.
JamesB

Przekonałem się, że używanie poprawionej wersji w pakiecie.json (bez karetki lub tyldy) jest znacznie czystszą opcją. To ratuje mnie przed whose build would fail one day because a random dependency got a breaking updatejakimś problemem. Choć pozostawia możliwość uzależnienia dziecka od tego samego problemu.
Ashwani Agarwal

58

Tak, najlepszą praktyką jest zameldowanie (TAK, ZAMELDOWANIE)

Zgadzam się, że spowoduje to dużo hałasu lub konfliktu, gdy zobaczysz różnicę. Ale korzyści to:

  1. gwarantuje dokładnie taką samą wersję każdego pakietu . Ta część jest najważniejsza przy budowaniu w różnych środowiskach w różnych momentach. Możesz używać ^1.2.3w swoim package.json, ale jak możesz upewnić się, że za każdym razem npm installwybierzesz tę samą wersję na maszynie deweloperskiej i serwerze kompilacji, szczególnie te pakiety zależności pośrednich? Cóż, package-lock.jsonzapewni. (Za pomocą npm ciktórego instaluje pakiety oparte na pliku blokady)
  2. usprawnia proces instalacji.
  3. pomaga w nowej funkcji kontroli npm audit fix(myślę, że funkcja kontroli pochodzi z npm wersji 6).

3
O ile mi wiadomo, nigdy nie używanie semvera (którego i tak nie rozumieją npm devs) nie powinno dawać takiego samego zachowania jak posiadanie pliku blokującego przynajmniej w 99% przypadków. Z mojego własnego doświadczenia wynika, że ​​kopie zapasowe semver występują głównie w pakietach podstawowych (bezpośrednie zależności, nieudolne narzędzia do zbierania dat jquery itp.). Moje osobiste doświadczenia z npm polegają na tym, że pliki blokad były na zawsze hałasem. Mam nadzieję, że ta mądrość pozostała niezmieniona w przypadku najnowszych wersji.
Svend

13
+1 za wzmiankę npm ci. Ludzie często wspominają, że package-lock.jsonpozwala na deterministyczną instalację pakietów, ale prawie nigdy nie wspominają o komendzie, która ułatwia to zachowanie! Wiele osób prawdopodobnie błędnie zakłada, że npm installinstaluje dokładnie to, co jest w pliku blokady ...
ahaurat

npm ci nie ma w npm 5.
dpurrington

Dziękuję Ci! Sensowne jest zatwierdzenie pliku package-lock.json tylko wtedy, gdy używasz npm ci. Twój zespół / główny programista może zdecydować, kiedy zaktualizować. Jeśli wszyscy po prostu arbitralnie to popełniają, nie ma sensu, a to po prostu powoduje hałas w twoim repozytorium. Dokumentacja NPM powinna to wyjaśnić. Myślę, że większość programistów jest po prostu zdezorientowana tą funkcją.
adampasz

@ adampasz faktycznie każdy programista może zatwierdzić plik blokady, a po przejściu testów i scaleniu druga gałąź po prostu odnawia plik blokady, jeśli w jakiś sposób pakiety zostaną zmienione (nie zmieniamy pliku package.json często, nie mamy do czynienia z tym problemem (
Xin

38

Nie zatwierdzam tego pliku w moich projektach. Jaki jest sens ?

  1. To jest generowane
  2. Jest to przyczyną błędu integralności kodu SHA1 w gitlab z kompilacjami gitlab-ci.yml

Chociaż prawdą jest, że nigdy nie używam ^ w pakiecie.json do bibliotek, ponieważ miałem z tym złe doświadczenia.


11
Chciałbym, aby można było to wyjaśnić bardziej w dokumentach npm - Przydałoby się mieć zarys tego, co konkretnie tracisz, nie zobowiązując się package-lock.json. Niektóre repozytoria mogą nie wymagać korzyści, które z tego wynikają, i wolą nie mieć automatycznie generowanej treści w źródle.
PotatoFarmer

2
Widzę, jak to może być przydatne do debugowania (na przykład różnic między dwiema blokadami), aby pomóc rozwiązać problemy. Wydaje mi się, że można go również wykorzystać do zapobiegania tego rodzaju problemom, ale może to być również kłopot ze wspólnym repozytorium, w którym mogą wystąpić konflikty scalania z tego powodu. Na początek chcę uprościć sprawę, po prostu użyję samodzielnie pliku package.json, dopóki nie zobaczę, że istnieje potrzeba użycia pliku package-lock.json.
radtek

6
Nie możesz używać ^ w pliku package.json, ale możesz być pewien, że twoje zależności go nie używają?
neiker

35

Do ludzi narzekających na hałas podczas wykonywania git diff:

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

Użyłem aliasu:

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

Aby zignorować pakiet-lock.json w plikach diff dla całego repozytorium (wszyscy go używający), możesz dodać to do .gitattributes:

package-lock.json binary
yarn.lock binary

Spowoduje to różnice, które pokazują „Pliki binarne a / package-lock.json i b / package-lock.json różnią się przy każdej zmianie pliku blokady pakietu. Dodatkowo niektóre usługi Git (zwłaszcza GitLab, ale nie GitHub) również wykluczą te pliki (nie zmieniły się już 10 000 wierszy!) z różnic podczas przeglądania online.


1
Mam gd() { git diff --color-words $1 $2 -- :!/yarn.lock :!/package-lock.json; }w moim .bashrc zamiast aliasu.
apostl3pol

16

Tak, możesz zatwierdzić ten plik. Z oficjalnych dokumentów npm :

package-lock.jsonjest generowany automatycznie dla wszystkich operacji, w których npmmodyfikuje się node_modulesdrzewo lub package.json. Opisuje dokładnie wygenerowane drzewo, dzięki czemu kolejne instalacje mogą generować identyczne drzewa, niezależnie od pośrednich aktualizacji zależności.

Ten plik ma być przeznaczony do repozytoriów źródłowych [.]


13
Czy instalacja nie zawsze aktualizuje moduły node_moduły, a zatem aktualizuje pakiet-lock.json?
Tim Gautier,

2
Nie, możesz uruchomić, npm ciaby zainstalować z pliku package-lock.json
William Hampshire

Musisz podkreślić w swojej odpowiedzi, że MUSISZ użyć npm ci w kompilacji ciągłej integracji, jeśli masz pakiet-lock.json na repozytorium
MagicLAMP

6

Wyłącz pakiet-lock.json globalnie

wpisz w swoim terminalu:

npm config set package-lock false

to naprawdę działa dla mnie jak magia


2
to tworzy ~/.npmrc(przynajmniej na moich makach) z zawartością package-lock=falsei to samo można zrobić w każdym konkretnym projekcie obok node_modules/(np.echo 'package-lock=false' >> .npmrc
Jim,

6
to dla mnie zabawne, że byłoby to negatywne. społeczność npm nie może zaakceptować faktu, że automatyczne generowanie package-lock.json było złym zaangażowaniem społeczności. nie powinieneś robić rzeczy, które mogą wpłynąć na proces zespołu. powinna być opcja włączenia, a nie wymuszona. ile osób po prostu dodaje „git add *”, a nawet tego nie zauważa i nie spieszy kompilacji. Jeśli masz jakikolwiek przepływ oparty na scalaniu, wiem, że git flow jest jak Biblia dla ludzi, którzy go używają, to nie zadziała. nie możesz mieć generacji podczas scalania! wersja npm jest zepsuta, pakiet: 1.0.0 powinien być deterministyczny!
Eric Twilegar,

3
dlaczego jest to obniżone? jest to oczywiście uzasadniony sposób wyłączenia funkcji, która nie działa. I chociaż nie odpowiada na pytanie jako takie, zadaje pytanie. tzn. nie potrzebuje już odpowiedzi. Kciuki w górę ode mnie :)
Superole,

Powodem, dla którego robi się to słabo oceniane, jest to, że po prostu wyłączasz funkcję.
Raza,

5

Tak, standardową praktyką jest popełnienie pliku package-lock.json

Głównym powodem popełnienia pliku package-lock.json jest to, że wszyscy w projekcie korzystają z tej samej wersji pakietu.

Plusy: -

  • Jeśli przestrzegasz ścisłej wersji i nie pozwalasz na automatyczną aktualizację do głównych wersji, aby uchronić się przed niezgodnymi wstecznymi zmianami w pakietach innych firm, popełnienie blokady pakietu bardzo pomaga.
  • Jeśli zaktualizujesz konkretny pakiet, zostanie on zaktualizowany w pliku package-lock.json, a wszyscy korzystający z repozytorium zostaną zaktualizowani do tej konkretnej wersji, gdy przyjmą zmiany.

Cons:-

  • Może sprawić, że twoje żądania ściągnięcia będą wyglądać brzydko :)

Edycja: - instalacja npm nie upewni się, że wszyscy w projekcie są w tej samej wersji pakietu. npm ci ci w tym pomoże.


4
Wady zniknęłyby, gdybyś użył npm cizamiast npm install.
k0pernikus


1
„Wszyscy w projekcie będą korzystali z tej samej wersji pakietu, wszystko co musisz zrobić, to zainstalować npm” Nieprawda, zamiast tego musisz użyć „npm ci”
reggaeguitar

Dzięki, @reggaeguitar. Aktualizuję moją odpowiedź na to.
Nikhil Mohadikar

2

Używam npm do generowania zminimalizowanego / uglifikowanego css / js i wygenerowania javascript potrzebnego na stronach obsługiwanych przez aplikację django. W moich aplikacjach Javascript działa na stronie, aby tworzyć animacje, czasami wykonuję wywołania ajax, pracuję w ramach VUE i / lub współpracuję z css. Jeśli pakiet-lock.json ma pewną nadrzędną kontrolę nad tym, co znajduje się w pakiecie.json, może być konieczne, aby istniała jedna wersja tego pliku. Z mojego doświadczenia wynika, że ​​albo nie wpływa to na to, co jest instalowane przez npm install, albo jeśli tak, to nie wpłynęło to negatywnie na aplikacje, które wdrażam według mojej wiedzy. Nie używam mongodb ani innych takich aplikacji, które są tradycyjnie cienkimi klientami.

Usuwam pakiet-lock.json z repozytorium, ponieważ instalacja npm generuje ten plik, a instalacja npm jest częścią procesu wdrażania na każdym serwerze, na którym działa aplikacja. Kontrola wersji węzła i npm odbywa się ręcznie na każdym serwerze, ale uważam, że są takie same.

Po npm installuruchomieniu na serwerze zmienia pakiet-lock.json, a jeśli wystąpią zmiany w pliku, który jest rejestrowany przez repozytorium na serwerze, następne wdrożenie WONT pozwala wyciągnąć nowe zmiany z początku. Oznacza to, że nie można wdrożyć, ponieważ ściągnięcie zastąpi zmiany wprowadzone w pliku package-lock.json.

Nie można nawet zastąpić lokalnie generowanego pliku package-lock.json tym, co znajduje się w repozytorium (zresetować główny wzorzec dysku twardego), ponieważ npm będzie narzekać, gdy wyda polecenie, jeśli pakiet-lock.json nie odzwierciedla tego, co jest w repozytorium node_modules z powodu instalacji npm, tym samym przerywając wdrożenie. Teraz, jeśli to wskazuje, że w module node_modules zostały zainstalowane nieco inne wersje, to nigdy nie sprawiło mi to problemów.

Jeśli node_modules nie znajduje się na twoim repozytorium (i nie powinno tak być), pakiet-lock.json powinien zostać zignorowany.

Jeśli czegoś brakuje, proszę o poprawienie mnie w komentarzach, ale punkt, w którym wersjonowanie pochodzi z tego pliku, nie ma sensu. Plik package.json zawiera numery wersji i zakładam, że ten plik służy do budowania pakietów, gdy nastąpi instalacja npm, ponieważ kiedy go usuwam, instalacja npm narzeka w następujący sposób:

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'

kompilacja kończy się niepowodzeniem, jednak podczas instalowania modułów node_modules lub stosowania npm do kompilacji js / css nie zgłoszę żadnych skarg, jeśli usunę pakiet 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 ...

Żeby dodać, teraz oddałem mój pakiet-lock.json do mojego repozytorium i używam npm ci w moim wdrożeniu ansible, które, jak sądzę, usuń node_modules, i instaluje wszystko w package-lock.json bez aktualizacji. To pozwala mojemu facetowi z przodu zaktualizować javascript bez konieczności ręcznej interwencji we wdrażaniu.
MagicLAMP
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.