Czy folder „node_modules” powinien być uwzględniony w repozytorium git

Odpowiedzi:

177

Odpowiedź nie jest tak łatwa, jak sugeruje Alberto Zaccagni. Jeśli tworzysz aplikacje (zwłaszcza aplikacje korporacyjne), włączenie node_modules w repozytorium git jest opłacalnym wyborem, a wybór opcji zależy od projektu.

Ponieważ bardzo dobrze argumentował przeciwko node_modules, skoncentruję się na argumentach za nimi.

Wyobraź sobie, że właśnie skończyłeś aplikację korporacyjną i będziesz musiał ją wspierać przez 3-5 lat. Na pewno nie chcesz polegać na czyimś module npm, który może jutro zniknąć i nie możesz już aktualizować swojej aplikacji.

Lub masz swoje prywatne moduły, które nie są dostępne w Internecie i nie możesz zbudować aplikacji w Internecie. A może z jakiegoś powodu nie chcesz polegać na ostatecznej kompilacji w usłudze npm.

Możesz znaleźć wady i zalety w tym artykule Addy Osmani (chociaż dotyczy to Bower, jest to prawie taka sama sytuacja). Skończę cytatem ze strony domowej Bowera i artykułu Addy:

„Jeśli nie tworzysz pakietu, który ma być używany przez innych (np. Tworzysz aplikację internetową), zawsze powinieneś sprawdzać zainstalowane pakiety w kontroli źródła”.

ivoszz
źródło
6
Całkowicie się z tym zgadzam. Nie chcę, aby nasz system kompilacji dla przedsiębiorstw wymagał połączenia z Internetem w celu pomyślnej kompilacji, ponieważ musi pobierać zależności, które, mam nadzieję, nadal istnieją. Dzięki.
deadlydog
9
@Alberto Zaccagni Wierzę, że miałeś rację za pierwszym razem. Jeśli naprawdę tworzysz aplikację dla przedsiębiorstw, powinieneś używać narzędzi dla przedsiębiorstw. Artifactory i npm-artifactory powinny być używane do ochrony projektów przed znikaniem z internetu. Nawet w przypadku małych projektów jest to czystsze niż posiadanie kilku kopii tej samej rzeczy wpisanej do kontroli źródła.
Ted Bigham
10
Po problemie lewego pada myślę, że zdecydowanie nie jest złym pomysłem śledzenie node_modules.
Léo Lam
6
Ważny aspekt, o którym nikt nie wspomniał. Jeśli twoje node_modules są w VCS - przełączanie gałęzi jest po prostu git checkout foo. Jeśli node_modules nie są objęte VCS - przełączanie gałęzi jest git checkout foo ; npm installi cokolwiek twoja obecna wersja NPM wymaga do działania;)
Ivan Kleshnin
7
Najczystszym rozwiązaniem dla przedsiębiorstwa byłoby hostowanie wewnętrznego repozytorium npm dostępnego dla intranetu, które zawiera wszystkie wersje używanych modułów, i nie wpisywanie node_modules z kodem źródłowym. Twój system kompilacji będzie odnosił się do wewnętrznego repozytorium węzłów.
user2867288
104

Szczegóły modułów są przechowywane packages.json, to wystarczy. Nie ma potrzeby meldowania się node_modules.

Ludzie używali node_moduleskontroli wersji do blokowania zależności modułów, ale z powłoką npm, która nie jest już potrzebna.

Kolejne uzasadnienie tego punktu, o czym @ChrisCM napisał w komentarzu:

Warto również zauważyć, że wszelkie moduły zawierające rozszerzenia natywne nie będą współpracować z architekturą i wymagają przebudowy. Przedstawienie konkretnego uzasadnienia dla NIEuwzględnienia ich w repozytorium.

Alberto Zaccagni
źródło
10
Prosto i na temat +1. Warto również zauważyć, że wszelkie moduły zawierające rozszerzenia natywne nie będą współpracować z architekturą i wymagają przebudowy. Przedstawienie konkretnego uzasadnienia dla NIEuwzględnienia ich w repozytorium.
ChrisCM
3
Nie do końca, jest to uzasadnienie dla używania odtwarzalnego środowiska deweloperskiego przy użyciu np. Włóczęgi. Powinien działać tylko na jednej architekturze.
Robin Smith
20

Odradzałbym sprawdzanie w node_modules na przykład pakietów takich jak PhantomJS i node-sass, które instalują odpowiedni plik binarny dla bieżącego systemu.

Oznacza to, że jeśli jeden programista działa npm installw systemie Linux i sprawdza w node_modules - nie będzie działać dla innego dewelopera, który sklonuje repozytorium w systemie Windows.

Lepiej jest sprawdzić w paczkach tar, które npm instalują pliki do pobrania i wskazać npm-shrinkwrap.jsonje. Możesz zautomatyzować ten proces za pomocą shrinkpack .

Jamie Mason
źródło
Ale czy npm install --global shrinkpacksamo w sobie nie ma odroczonej słabości, wymagając innych pakietów, z którymi następnie instalują skurczone pakiety? Jest to sprzeczne z radą Addy.
danjah
czy mógłbyś przeformułować pytanie, proszę @danjah? Przepraszam, nie rozumiem do końca.
Jamie Mason
Z tego, co opisujesz, zależność od shrinkpackjest wymagana, aby następnie niezawodnie zainstalować zależności kompilacji. W związku z tym sama instalacja narzędzia kompilacji staje się słabością argumentu przeciwko poddawaniu wszystkich zależności kompilacji kontroli wersji.
danjah
1
Myślę, że wystarczy sprawdzić pliki blokujące (package-lock.json; yarn.lock) przynajmniej według TFM: docs.npmjs.com/files/package-lock.json
aimass
1
dostaniesz przewidywalny wykres zależności podczas używania pliku blokującego i nie będziesz podatny na problemy omawiane wokół PhantomJS i node-sass itp. na różnych platformach. Będziesz potrzebował połączenia internetowego i oczywiście do działania rejestru.
Jamie Mason
7

Widzę, że ten temat jest dość stary. Ale brakuje mi aktualizacji argumentów tutaj podanych z powodu zmienionej sytuacji w ekosystemie npm.

Zawsze radziłbym nie poddawać node_modules kontroli wersji. Prawie wszystkie korzyści z tego, wymienione w kontekście zaakceptowanej odpowiedzi, są obecnie dość nieaktualne.

  1. Opublikowanych pakietów nie można już tak łatwo odwołać z rejestru npm. Nie musisz więc obawiać się utraty zależności, na których wcześniej polegał Twój projekt.

  2. Umieszczenie pliku package-json.lock w VCS pomaga w przypadku często aktualizowanych zależności, które prawdopodobnie skutkują różnymi konfiguracjami, chociaż polegają na tym samym pliku package.json.

Tak więc umieszczenie node_modules w VCS w przypadku posiadania narzędzi do kompilacji offline może być uważane za jedyny dopuszczalny przypadek użycia. Jednak node_modules zwykle rośnie dość szybko. Każda aktualizacja zmieni wiele plików. A to wpływa na repozytoria na różne sposoby. Jeśli naprawdę weźmiesz pod uwagę długoterminowe skutki, to również może być przeszkodą.

Scentralizowane VCS, takie jak svn, wymagają przesyłania zatwierdzonych i wyewidencjonowanych plików przez sieć, co będzie piekielnie powolne, jeśli chodzi o wyewidencjonowywanie lub aktualizację folderu node_modules.

Jeśli chodzi o git, ta duża liczba dodatkowych plików spowoduje natychmiastowe zanieczyszczenie repozytorium. Należy pamiętać, że git nie śledzi różnic między wersjami żadnego pliku, ale przechowuje kopie dowolnej wersji pliku, gdy tylko zmieni się jeden znak. Każda aktualizacja dowolnej zależności spowoduje kolejny duży zestaw zmian. Twoje repozytorium git szybko się rozrośnie, ponieważ ma to wpływ na kopie zapasowe i zdalną synchronizację. Jeśli zdecydujesz się później usunąć node_modules z repozytorium git, nadal jest on jego częścią ze względów historycznych. Jeśli rozdzieliłeś swoje repozytorium git na jakiś zdalny serwer (np. W celu wykonania kopii zapasowej), wyczyszczenie go jest kolejnym bolesnym i podatnym na błędy zadaniem, z którym będziesz musiał się zmierzyć.

Tak więc, jeśli zależy Ci na wydajnych procesach i chcesz, aby rzeczy były „małe”, wolałbym raczej użyć oddzielnego repozytorium artefaktów, takiego jak Nexos Repository (lub po prostu jakiś serwer HTTP z archiwami ZIP), zapewniający wcześniej pobrany zestaw zależności do pobrania.

Thomas Urban
źródło
6

Brak śledzenia node_modulesz kontrolą źródła jest właściwym wyborem, ponieważ niektóre moduły NodeJS, takie jak sterownik MongoDB NodeJS, używają dodatków NodeJS C ++. Te dodatki są kompilowane podczas uruchamiania npm installpolecenia. Więc kiedy śledzisz node_moduleskatalog, możesz przypadkowo zatwierdzić plik binarny specyficzny dla systemu operacyjnego.

MZ
źródło
3

Zgadzam się z ivoszz , że czasami warto sprawdzić folder node_modules, ale ...


scenariusz 1:

Jeden scenariusz: używasz pakietu, który zostanie usunięty z npm. Jeśli masz wszystkie moduły w folderze node_modules, nie będzie to dla ciebie problemem. Jeśli masz tylko nazwę pakietu w pliku package.json, nie możesz jej już pobrać. Jeśli paczka ma mniej niż 24 godziny, możesz ją łatwo usunąć z npm. Jeśli ma więcej niż 24 godziny, musisz się z nimi skontaktować. Ale:

Jeśli skontaktujesz się z pomocą techniczną, sprawdzą, czy usunięcie tej wersji pakietu nie spowoduje przerwania innych instalacji. Jeśli tak, nie usuniemy go.

Czytaj więcej

Więc szanse na to są niskie, ale jest scenariusz 2 ...


scenariusz 2:

Inny scenariusz, w którym ma to miejsce: Tworzysz wersję korporacyjną oprogramowania lub bardzo ważne oprogramowanie i piszesz w pliku package.json:

"dependencies": {
    "studpid-package": "~1.0.1"
}

Używasz metody function1(x)tego pakietu.

Teraz programiści studpid-package zmieniają nazwę metody function1(x)na function2(x)i robią błąd ... Zmieniają wersję swojego pakietu z 1.0.1na 1.1.0. To problem, ponieważ npm installnastępnym razem zaakceptujesz wersję, 1.1.0ponieważ użyłeś tyldy ( "studpid-package": "~1.0.1").

Dzwonienie function1(x)może teraz powodować błędy i problemy.


Ale:

Wypchnięcie całego folderu node_modules (często ponad 100 MB) do repozytorium będzie kosztować miejsce w pamięci. Kilka KB (tylko package.json) w porównaniu z setkami MB (package.json i node_modules) ... Pomyśl o tym.

Możesz to zrobić / powinieneś o tym pomyśleć, jeśli:

  • oprogramowanie jest bardzo ważne.

  • kosztuje cię pieniądze, gdy coś się nie powiedzie.

  • nie ufasz rejestrowi npm. npm jest scentralizowany i teoretycznie może zostać zamknięty.

Nie musisz publikować folderu node_modules w 99,9% przypadków, jeśli:

  • tworzysz oprogramowanie tylko dla siebie.

  • zaprogramowałeś coś i po prostu chcesz opublikować wynik na GitHub, ponieważ ktoś może być tym zainteresowany.


Jeśli nie chcesz, aby node_modules znajdowały się w Twoim repozytorium, po prostu utwórz .gitignoreplik i dodaj linię node_modules.

ndsvw
źródło
1
Kolejną wadą „publikowania folderu node_modules” może być: wywołanie npm installw systemie Windows i MacOS może generować różne pliki (pliki zależne od systemu operacyjnego) w niektórych pakietach. Ale nie jestem tego pewien. Czy ktoś może zweryfikować, że to prawda?
ndsvw
2
„scenariusz 2”: dlatego się zobowiązujesz package-lock.json. Jeśli w przyszłości wystąpi problem z aktualizacją pakietu studpid, możesz przywrócić plik blokady, aby znaleźć dokładną wersję, która działała dla Ciebie.
ToolmakerSteve
2

Chciałbym zaoferować alternatywę środka drogi.

  1. Nie dodawaj node_modulesdo gita.
  2. Użyj package-lock.jsonpliku, aby ustalić wersje zależności.
  3. W procesie CI lub wydawania, kiedy wydasz wersję, wykonaj kopię folderu node_modules i wykonaj kopię zapasową (np. W chmurze).

W rzadkich przypadkach, gdy nie możesz uzyskać dostępu do NPM (lub innych rejestrów, z których korzystasz) lub określonego pakietu w NPM, masz kopię node_modules i możesz kontynuować pracę do czasu przywrócenia dostępu.

Martin Capodici
źródło
0

Jeszcze jedna rzecz do rozważenia: zameldowanie node_modulesutrudnia / uniemożliwia skorzystanie z różnicy między dependenciesi devDependencies.

Z drugiej strony jednak można by powiedzieć, że uspokajające jest wypchnięcie do produkcji dokładnie tego samego kodu, który przeszedł przez testy - włączając w to devDependencies.

Jan Żankowski
źródło
„do produkcji dokładnie tego samego kodu, który przeszedł testy”: Po to masz Dockera. Lub menedżer pakietów systemu operacyjnego, taki jak rpm. Nie odbudowujesz kodu między testem a produkcją, prawda? devDependencies pomogła w zbudowaniu ostatecznego kodu, ale nie ma miejsca we wdrożeniu, ani w testach, ani w wersji produkcyjnej.
Według Wiklandera
Czy pomogłoby, gdyby devDependencies były w swoim własnym pliku package.json o jeden katalog wyżej niż katalog „src”? Ponieważ moduły węzłów są przeszukiwane pod kątem uruchamiania w bieżącym katalogu, a następnie przechodzenia w górę, nadal powinieneś używać swoich zależności dev i oddzielenie modułów dev / src.
Alex
0

Nie jest wymagane wpisywanie modułów node_modules, jeśli zależności są wymienione w pliku package.json. Każdy inny programista może go po prostu uzyskać, wykonując instalację npm, a npm jest wystarczająco inteligentny, aby utworzyć node_modules w katalogu roboczym projektu.

Himanshu
źródło