Dlaczego "npm install" przepisuje blokadę pakietu.json?

Niedawno uaktualniłem do npm@5 . Mam teraz blokadę pakietów.plik json zawierający wszystko z pakietu.json . Spodziewałbym się, że po uruchomieniu npm install wersje zależności zostaną wyciągnięte z pliku blokady, aby określić, co powinno być zainstalowane w moim katalogu node_modules. Dziwne jest to, że kończy się to modyfikacją i przepisaniem mojego package-lock.plik json.

Na przykład plik blokady miał typescript określony jako w wersji 2.1.6. Następnie, po poleceniu npm install, wersja została zmieniona na 2.4.1. To zdaje się niszczyć cały cel pliku blokady.

Co mi umyka? Jak sprawić, by npm rzeczywiście szanował mój plik blokady?
Author: falinsky, 2017-07-10

11 answers

Aktualizacja 3: jak również wskazują inne odpowiedzi, Komenda npm ci została wprowadzona w npm 5.7.0 jako dodatkowy sposób na uzyskanie szybkich i powtarzalnych kompilacji w kontekście CI. Więcej informacji można znaleźć w dokumentacji i npm blog.


Update 2: problem dotyczący aktualizacji i wyjaśnienia dokumentacji to GitHub issue #18103.


Update 1: zachowanie opisane poniżej zostało naprawione w npm 5.4.2: obecnie zamierzone zachowanie jest opisane w wydaniu GitHub #17979.


Oryginalna odpowiedź: zachowanie package-lock.json zostało zmienione w npm 5.1.0 jak omówiono wissue #16866 . Zachowanie, które obserwujesz, jest najwyraźniej zamierzone przez npm od wersji 5.1.0.

Oznacza to, że {[2] } może nadpisać package-lock.json za każdym razem, gdy zostanie znaleziona nowsza wersja zależności W package.json. Jeśli chcesz skutecznie przypiąć zależności, musisz teraz podaj wersje bez prefiksu, np. musisz zapisać je jako 1.2.0 zamiast ~1.2.0 lub ^1.2.0. Wtedy kombinacja package.json i package-lock.json Da powtarzalne buildy. Żeby było jasne: package-lock.json sam już nie blokuje zależności poziomu głównego!

Czy ta decyzja projektowa była dobra, czy nie jest dyskusyjna, trwa dyskusja wynikająca z tego zamieszania na Githubie w numerze #17979. (W moich oczach jest to wątpliwa decyzja; przynajmniej nazwa lock nie trzyma to prawda.)

Jeszcze jedna uwaga: istnieje również ograniczenie dla rejestrów, które nie obsługują niezmiennych pakietów, np. gdy ściągasz Pakiety bezpośrednio z Githuba zamiast npmjs.org. Patrz ta dokumentacja blokad pakietów , aby uzyskać dalsze wyjaśnienie.

 461
Author: jotaen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-10 16:09:16

Odkryłem, że będzie nowa wersja npm 5.7.1 z nowym poleceniem npm ci, które zainstaluje się tylko z package-lock.json

Nowe polecenie npm ci instaluje się tylko z pliku blokady. Jeśli Twoja paczka.json i Twój plik blokady są zsynchronizowane, a następnie zgłosi błąd.

Działa poprzez wyrzucenie node_modules i odtworzenie go od zera.

Poza gwarancją, że dostaniesz tylko to, co jest w Twoim pliku blokady, jest to również znacznie szybsze (2x-10x!) niż npm zainstalować, gdy nie zaczyna się z node_modules.

Jak można wziąć od nazwy, oczekujemy, że będzie to wielki Dobrodziej dla środowisk ciągłej integracji. Spodziewamy się również, że osoby, które wykonują wdrożenia produkcyjne z tagów git, zauważą duże zyski.

 183
Author: Ivan Shcherbakov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

Użyj nowo wprowadzonego

npm ci

Npm ci obiecuje największe korzyści dla dużych zespołów. Dając programistom możliwość "podpisania" blokady pakietów promuje bardziej efektywną współpracę między dużymi zespołami, a możliwość zainstalowania dokładnie tego, co znajduje się w pliku blokady, może zaoszczędzić dziesiątki, jeśli nie setki godzin deweloperów miesięcznie, uwalniając Zespoły do spędzania więcej czasu na budowaniu i wysyłaniu niesamowitych rzeczy.

Przedstawiamy npm ci dla szybszego i bardziej niezawodnego buduje

 103
Author: Gal Margalit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-26 14:59:36

Krótka Odpowiedź:

  • npm install honors package-lock.json tylko wtedy, gdy spełnia wymagania pakietu.json.
  • Jeśli nie spełnia tych wymagań, pakiety są aktualizowane i blokada pakietów jest nadpisywana.
  • Jeśli chcesz, aby instalacja nie powiodła się, zamiast nadpisywać package-lock, użyj npm ci.

Oto scenariusz, który może wyjaśnić rzeczy (zweryfikowane z NPM 6.3.0)

Deklarujesz zależność w pakiecie.JSON like:

"depA": "^1.0.0"

Potem robisz, {[5] } co wygeneruje blokadę pakietów.JSON z:

"depA": "1.0.0"
Kilka dni później ukazała się nowsza, mniejsza wersja "depA", powiedzmy "1.1.0".]}
npm ci       # respects only package-lock.json and installs 1.0.0

npm install  # also, respects the package-lock version and keeps 1.0.0 installed 
             # (i.e. when package-lock.json exists, it overrules package.json)

Następnie ręcznie aktualizujesz pakiet.json do:

"depA": "^1.1.0"

Następnie powtórz:

npm ci      # will try to honor package-lock which says 1.0.0
            # but that does not satisfy package.json requirement of "^1.1.0" 
            # so it would throw an error 

npm install # installs "1.1.0" (as required by the updated package.json)
            # also rewrites package-lock.json version to "1.1.0"
            # (i.e. when package.json is modified, it overrules the package-lock.json)
 82
Author: Ahmad Abdelghany,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-08-23 10:54:25

Użyj polecenia npm ci zamiast npm install.

"ci" oznacza "ciągłą integrację".

Zainstaluje zależności projektu oparte na package-lock.plik json zamiast pakietu pobłażliwego.zależności plików json.

Będzie produkować identyczne buildy do Twoich kolegów z drużyny, a także jest znacznie szybszy.

Możesz przeczytać więcej na ten temat w tym wpisie na blogu: https://blog.npmjs.org/post/171556855892/introducing-npm-ci-for-faster-more-reliable

 22
Author: Daniel Tonon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-12 09:01:50

W przyszłości będziesz mógł użyć znacznika --from-lock-file (lub podobnego), aby zainstalować Tylko z package-lock.json bez modyfikowania go.

Będzie to przydatne dla CI, itp. środowiska, w których ważne są powtarzalne budowle.

Zobacz https://github.com/npm/npm/issues/18286 do śledzenia funkcji.

 8
Author: Timothy Higinbottom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-06 20:25:30

Wygląda na to, że ten problem został naprawiony w npm v5.4.2

Https://github.com/npm/npm/issues/17979

(przewiń w dół do ostatniego komentarza w wątku)

Update

Faktycznie poprawione w 5.6.0. W wersji 5.4.2 pojawił się błąd międzyplatformowy, który powodował, że problem nadal występował.

Https://github.com/npm/npm/issues/18712

Update 2

Zobacz moją odpowiedź proszę.: https://stackoverflow.com/a/53680257/1611058

npm ci to polecenie, którego powinieneś używać podczas instalowania istniejących projektów.

 8
Author: Daniel Tonon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-12-08 06:51:42

Prawdopodobnie masz coś w stylu:

"typescript":"~2.1.6"

W Twoim package.json który npm aktualizuje do najnowszej wersji minor, w Twoim przypadku jest 2.4.1

Edit: pytanie z OP

Ale to nie wyjaśnia dlaczego "npm install" zmieniłby plik blokady. Czy plik blokady nie jest przeznaczony do tworzenia powtarzalnej kompilacji? Jeśli tak, niezależnie od wartości semver, powinien nadal używać tego samego 2.1.6 wersja.

Odpowiedź:

To ma na celu zablokowanie twoje drzewo zależności. Powiedzmy, że typescript v2.4.1 wymaga widget ~v1.0.0. Po zainstalowaniu npm chwyty widget v1.0.0. Później twój kolega programista (lub ci build) czy npm instaluje i dostaje typescript v2.4.1 ale widget został zaktualizowano do widget v1.0.1. Teraz twój moduł węzła nie jest zsynchronizowany. To jest tym, co package-lock.json zapobiega.

Lub bardziej ogólnie:

Jako przykład rozważ

Pakiet A:

{ "Nazwa": "A", "wersja": "0.1.0", " zależności": { "B": "

Pakiet B:

{"Nazwa": "B", "Wersja": "0.0.1", " zależności": { "C": "

I pakiet C:

{"nazwa": "C", "Wersja": "0.0.1"}

Jeśli są to jedyne wersje A, B I C dostępne w rejestrze, a następnie normalny npm zainstalować zainstaluje:

[email protected] -- [email protected] -- [email protected]

Jednakże, jeśli [email protected] jest publikowany, a następnie świeży npm install a zainstaluje:

[email protected] -- [email protected] -- [email protected] zakładając, że nowa wersja nie zmodyfikowała zależności B. Oczywiście nowa wersja B może zawierać nową wersja C i dowolna liczba nowych zależności. Jeśli takie zmiany są niepożądane, autor może określić zależność od [email protected]. Jeśli jednak autor A i autor B nie są tą samą osobą, to nie ma mowy, aby autor a powiedział, że nie chce wciągać nowe wersje C, gdy B w ogóle się nie zmieniło.


OP Pytanie 2: więc pozwól mi zobaczyć, czy dobrze rozumiem. What you ' re mówi się, że plik lock Określa wersje drugorzędnego zależności, ale nadal opiera się na rozmytym dopasowaniu pakietu.json aby określić zależności najwyższego poziomu. Czy to prawda?

Odpowiedź: Nie. package-lock blokuje całe drzewo pakietów, w tym Pakiety root opisane w package.json. If typescript is locked at 2.4.1 in Twoje package-lock.json, powinno tak pozostać, dopóki nie będzie zmieniony. I powiedzmy, że jutro typescript wyda wersję 2.4.2. Jeśli sprawdzę Twój oddział i uruchomię npm install, npm uszanuje lockfile I install 2.4.1.

Więcej na package-lock.json:

Package-lock.json jest automatycznie generowany dla wszelkich operacji, w których npm modyfikuje drzewo node_modules lub pakiet.json. Opisuje dokładne drzewo, które zostało wygenerowane, tak aby kolejne instalacje były w stanie wygenerować identyczne drzewa, niezależnie od pośrednich aktualizacji zależności.

[19]} ten plik jest przeznaczony do przeniesienia do repozytoriów źródłowych i służy różnym celom:

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

Zapewnienie użytkownikom możliwości "podróży w czasie" do poprzednich stanów node_modules bez konieczności zatwierdzania katalogu siebie.

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

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

Https://docs.npmjs.com/files/package-lock.json

 4
Author: Matt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-11 13:55:39

Prawdopodobnie powinieneś użyć czegoś takiego

npm ci

Zamiast używać npm install jeśli nie chcesz zmieniać wersji pakietu.

Zgodnie z oficjalną dokumentacją, zarówno npm install jak i npm ci instalują zależności potrzebne do projektu.

Główna różnica polega na tym, że npm install instaluje Pakiety biorąc packge.json jako odniesienie. Gdzie w przypadku npm ci, instaluje Pakiety biorąc package-lock.json jako odniesienie, upewniając się za każdym razem pakiet exact jest zainstalowany.

 3
Author: Sengottaian Karthik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-14 13:56:47

Na ich stronie github jest otwarty problem: https://github.com/npm/npm/issues/18712

Ten problem jest najpoważniejszy, gdy deweloperzy używają różnych systemów operacyjnych.

 1
Author: hrdwdmrbl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-22 00:08:24

EDIT: nazwa "lock" jest trudna, jej NPM próbuje dogonić Yarn. To nie jest zamknięty plik. package.json jest plikiem ustalonym przez użytkownika, który po "zainstalowaniu" wygeneruje drzewo katalogów node_modules, które następnie zostanie zapisane w package-lock.json. Więc widzisz, to odwrotnie - wersje zależności będą pobierane z package.json jak zawsze, a package-lock.json powinny być nazwane package-tree.json

(mam nadzieję, że to sprawiło, że moja odpowiedź stała się jaśniejsza, po tylu downvotach)


Uproszczona odpowiedź: package.json należy mieć swoje zależności jak zwykle, podczas gdy package-lock.json jest "dokładnym i co ważniejsze powtarzalnym drzewem node_modules" (zaczerpniętym z npm docs ).

Jeśli chodzi o podchwytliwą nazwę, to NPM próbuje nadrobić zaległości.
 1
Author: Bernardo Dal Corno,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-12 05:20:11