Jaka jest różnica między „instalacją npm” a „npm ci”?

215

Pracuję z ciągłą integracją i odkryłem polecenie npm ci .

Nie mogę zrozumieć, jakie są zalety korzystania z tego polecenia w moim przepływie pracy.

Czy to jest szybsze? Czy to sprawia, że ​​test jest trudniejszy?

Webwoman
źródło

Odpowiedzi:

327

Z dokumentów npm :

Krótko mówiąc, główne różnice między używaniem instalacji npm i npm ci to:

  • 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 ci zakończy działanie z błędem, zamiast aktualizować blokadę pakietu.
  • npm ci może instalować tylko całe projekty naraz: nie można dodawać indywidualnych zależności za pomocą tego polecenia.
  • Jeśli moduł node_modules jest już obecny, zostanie on automatycznie usunięty, zanim npm ci rozpocznie instalację.
  • Nigdy nie napisze w paczce.json ani w żadnej z blokad pakietów: instalacje są zasadniczo zawieszone.

Zasadniczo npm installczyta, package.jsonaby utworzyć listę zależności i używa package-lock.jsondo poinformowania, które wersje tych zależności należy zainstalować. Jeśli nie ma zależności package-lock.json, zostanie dodana przeznpm install .

npm ci(nazwany C ciągłe I ntegration) instaluje się bezpośrednio z zależnościami package-lock.jsoni zastosowań package.jsontylko, aby potwierdzić, że nie istnieją wersje niedopasowane. Jeśli brakuje jakichkolwiek zależności lub mają one niezgodne wersje, wygeneruje błąd .

Służy npm installdo dodawania nowych zależności i aktualizowania zależności od projektu. Zwykle używasz go podczas programowania po wyciągnięciu zmian aktualizujących listę zależności, ale npm ciw tym przypadku dobrym pomysłem może być użycie .

Użyj, npm cijeśli potrzebujesz deterministycznej, powtarzalnej kompilacji. Na przykład podczas ciągłej integracji, automatycznych zadań itp. Oraz podczas instalowania zależności po raz pierwszy zamiast npm install.

npm install

  • Instaluje pakiet i wszystkie jego zależności.
  • Zależności są sterowane przez npm-shrinkwrap.jsoni package-lock.json(w tej kolejności).
  • bez argumentów : instaluje zależności modułu lokalnego.
  • Może instalować pakiety globalne.
  • Zainstaluje wszelkie brakujące zależności w node_modules.
  • Może pisać do package.jsonlub package-lock.json.
    • W przypadku użycia z argumentem ( npm i packagename) może pisać package.jsondo dodania lub aktualizacji zależności.
    • w przypadku użycia bez argumentów ( npm i) może napisać, aby package-lock.jsonzablokować wersję niektórych zależności, jeśli nie ma ich już w tym pliku.

npm ci

  • Wymaga co najmniej npm v5.7.1 .
  • Wymaga package-lock.jsonlub npm-shrinkwrap.jsonmusi być obecny.
  • Zgłasza błąd, jeśli zależności między tymi dwoma plikami nie są zgodne package.json.
  • Usuwa node_modulesi instaluje wszystkie zależności jednocześnie.
  • Nigdy nie pisze do package.jsonlub package-lock.json.

Algorytm

Podczas gdy npm cigeneruje całe drzewo zależności z package-lock.jsonlub npm-shrinkwrap.json, npm install aktualizuje zawartośćnode_modules przy użyciu następującego algorytmu ( źródła ):

load the existing node_modules tree from disk
clone the tree
fetch the package.json and assorted metadata and add it to the clone
walk the clone and add any missing dependencies
  dependencies will be added as close to the top as is possible
  without breaking any other modules
compare the original tree with the cloned tree and make a list of
actions to take to convert one to the other
execute all of the actions, deepest first
  kinds of actions are install, update, remove and move
lucascaro
źródło
1
Nie wiedziałem, że mogę npm installnapisać do package.json. Czy wiesz, co mógłby tu napisać?
Veve
5
cóż, może to być nieco mylące ... napisze do package.json, gdy użyjesz go do zainstalowania, aktualizacji lub usunięcia zależności. Wyjaśnię to bardziej w tekście, dzięki!
lucascaro,
Gdzie udokumentowano ten algorytm? Tj. Jakie jest twoje źródło?
Yngvar Kristiansen
1
@YngvarKristiansen jest w dokumentacji npm, dodano link do konkretnej sekcji w celach informacyjnych
lucascaro
4
npm install packagemogli modyfikować zarówno package-lock.json a package.json , natomiast npm installwhithout argumenty by tylko modyfikowaćpackage-lock.json
knobo
20

npm ciusunie każdy istniejący folder node_modules i polega na package-lock.jsonpliku, aby zainstalować określoną wersję każdego pakietu. Jest znacznie szybszy niż instalacja npm, ponieważ pomija niektóre funkcje. Instalacja w stanie czystym jest świetna dla rurociągów ci / cd i kompilacji dokerów! Używasz go również do instalacji wszystkiego naraz, a nie konkretnych pakietów.

James Harrison
źródło
9

Dokumentacja, którą podłączyłeś, miała podsumowanie:

Krótko mówiąc, główne różnice między używaniem instalacji npm i npm ci to:

  • 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 ci zakończy działanie z błędem, zamiast aktualizować blokadę pakietu.
  • npm ci może instalować tylko całe projekty naraz: nie można dodawać indywidualnych zależności za pomocą tego polecenia.
  • Jeśli moduł node_modules jest już obecny, zostanie on automatycznie usunięty, zanim npm ci rozpocznie instalację.
  • Nigdy nie napisze w paczce.json ani w żadnej z blokad pakietów: instalacje są zasadniczo zawieszone.
OscarRyz
źródło
2

Polecenia mają bardzo podobną funkcjonalność, jednak różnica polega na podejściu zastosowanym do zainstalowania zależności określonych w plikach package.jsoni package-lock.json.

npm ciwykonuje czystą instalację wszystkich zależności aplikacji, ale npm installmoże pominąć niektóre instalacje, jeśli już istnieją w systemie. Problem może powstać, jeśli wersja już zainstalowana w systemie nie package.jsonjest wersją, którą zamierzasz zainstalować, tj. Zainstalowana wersja różni się od wersji „ wymaganej ”.

Inne różnice to takie, które npm cinigdy nie dotykają twoich package*.jsonplików. Zatrzyma instalację i wyświetli błąd, jeśli wersje zależności nie będą zgodne w plikach package.jsoni package-lock.json.

Możesz przeczytać o wiele lepsze wyjaśnienie z oficjalnych dokumentów tutaj .

Dodatkowo, może chcesz przeczytać o zamkach pakiet tutaj .

krishnakeshan
źródło
1

Warto pamiętać, że obrazy dokerów lekkich węzłów, takie jak alpine, nie mają zainstalowanego Pythona, z którego zależności node-gypkorzysta npm ci.

Myślę, że jest nieco uważane, że aby npm cidziałać, musisz zainstalować Pythona jako zależność w swojej kompilacji.

Więcej informacji tutaj Docker i npm - gyp ERR! nie w porządku

teseo
źródło
0

Podczas gdy wszyscy inni odpowiedzieli na różnice techniczne, nikt nie wyjaśnia, w jakich sytuacjach użyć obu.

Powinieneś ich używać w różnych sytuacjach.

npm installjest świetny do programowania i do CI, gdy chcesz buforować node_moduleskatalog. Kiedy tego użyć? Możesz to zrobić, jeśli tworzysz pakiet dla innych osób (NIE dołączasz go node_modulesdo takiego wydania) . Jeśli chodzi o buforowanie, należy zachować ostrożność, jeśli planowane jest obsługiwanie różnych wersji Node.jspamięci, które node_modulesmogą wymagać ponownej instalacji ze względu na różnice między Node.jswymaganiami środowiska wykonawczego. Jeśli chcesz trzymać się jednej wersji, trzymaj się najnowszej LTS.

npm cipowinien być używany, gdy chcesz przetestować i wydać aplikację produkcyjną (produkt końcowy, nie może być używany przez inne pakiety), ponieważ ważne jest, aby instalacja była jak najbardziej deterministyczna, instalacja potrwa dłużej, ale ostatecznie spowoduje Twoja aplikacja jest bardziej niezawodna (dołączasz do node_modulestakiej wersji) . Trzymaj się LTSwersji Node.js.

Bonus: Możesz je mieszać w zależności od tego, jak skomplikowany chcesz to zrobić. W gałęziach funkcji w gitpamięci podręcznej node_modulesmożna zwiększyć wydajność zespołów, a żądanie scalenia i gałęzie główne polegają na npm cideterministycznym wyniku.

K - Toksyczność w SO rośnie.
źródło