Jak wdrożyć aplikację Node.js z głęboką strukturą node_modules w systemie Windows?

91

Napotkałem ciekawy problem - najwyraźniej niektóre moduły Node.js mają tak głębokie hierarchie folderów, że polecenie kopiowania systemu Windows (lub PowerShell, Copy-Itemktórego w rzeczywistości używamy) trafia w niesławny błąd „ścieżka zbyt długa”, gdy ścieżka ma ponad 250 znaki długie.

Na przykład jest to hierarchia folderów, którą może utworzyć pojedynczy moduł Node:

node_modules\nodemailer\node_modules\simplesmtp\node_modules\
xoauth2\node_modules\request\node_modules\form-data\node_modules\
combined-stream\node_modules\delayed-stream\...

Wydaje się to szalone, ale jest rzeczywistością w przypadku modułów Node.

Musimy używać kopiuj-wklej podczas wdrażania (nie używamy "sprytnej" platformy docelowej, takiej jak Heroku, gdzie wdrożenie Git byłoby opcją) i jest to poważne ograniczenie w systemie Windows.

Czy nie ma polecenia npm lub czegoś, co skompaktowałoby node_modulesfolder lub może zawierało tylko to, co jest faktycznie konieczne w czasie wykonywania? (Moduły węzłów zwykle zawierają testfoldery itp., Których nie musimy wdrażać). Czy masz inne pomysły, jak to obejść? Nieużywanie systemu Windows niestety nie wchodzi w grę :)

Borek Bernard
źródło
1
Czy Twój projekt ma package.jsonz dependencieszestawem? Jeśli tak, czy możesz kopiować bez node_modulesi używać npm do installlub updatezależności?
Jonathan Lonowski
4
@JonathanLonowski Nasze środowisko wdrożeniowe nie obsługuje wykonywania npm installw środowisku docelowym, działa poprzez tworzenie lokalnie „pakietu wdrożeniowego” (w zasadzie ZIP plus niektóre metadane), który jest następnie przesyłany na maszynę docelową, rozpakowywany i gotowe. Więc muszę dołączyć node_modulesbezpośrednio.
Borek Bernard

Odpowiedzi:

24

npm v3 (wydany niedawno) rozwiązuje ten problem poprzez spłaszczenie zależności. Sprawdź informacje o wydaniu tutaj w https://github.com/npm/npm/releases/tag/v3.0.0 w flat flatsekcji.

I ostatni komentarz w tej sprawie https://github.com/npm/npm/issues/3697

RameshVel
źródło
5
Informacje o wydaniu dla flat flatsą teraz pochowane na innej stronie. Oto bezpośredni link: github.com/npm/npm/releases/tag/v3.0.0
John-Philip
Dzięki @ John-Philip, zaktualizowałem odpowiedź o nowy link
RameshVel
62

żeby dodać do tego ... kolejną rzeczą, która pomogła mi, była lista wszystkich zainstalowanych modułów z npm ls.

co da ci drzewo modułów i wersji ... stamtąd łatwo jest zidentyfikować, które z nich są duplikatami ... npm dedupenic dla mnie nie zrobiło. Nie jestem pewien, czy to błąd, czy co (Node v 10.16)

Po zidentyfikowaniu zduplikowanego modułu zainstaluj go w katalogu głównym node_module przy użyciu npm install [email protected] --save-dev. Wersja jest ważna.

potem wyczyściłem mój katalog node_modules i zrobiłem nowy npm install.

Krótka wersja

  1. npm ls aby uzyskać listę wszystkich zainstalowanych modułów.
  2. przejrzyj te moduły i zidentyfikuj zduplikowane moduły ( ważna jest wersja )
  3. npm install module@version --save-dev aby zainstalować te moduły w katalogu głównym node_modules i zaktualizować plik package.json.
  4. rmdir node_modules aby usunąć katalog node_modules.
  5. npm install aby ściągnąć nową kopię swoich zależności.

Kiedy to zrobiłem, wszystko było znacznie czystsze.

Polecam również skomentowanie pliku package.json, aby pokazać, które z nich zostały sprowadzone w celu spłaszczenia drzewa node_modules.

Ben Lesh
źródło
To działało świetnie dla mnie. Dziękuję Ci! Wybacz moją ignorancję, ale dlaczego moduły nie zawsze są instalowane na najwyższym poziomie?
Caleb
2
@Caleb prawdopodobnie dlatego, że różne moduły opierają się na różnych wersjach tego samego modułu, a może po prostu dlatego, że łatwiej jest po prostu zdobyć to, czego potrzeba, a następnie uwzględnić to ... Nie wiem.
Ben Lesh
7
Mimo wszystko dzięki za wskazówkę. Właśnie zdmuchnąłem około 1700 duplikatów plików z naszego projektu. Usuwanie rzeczy to moja ulubiona część bycia programistą! Ponadto dla każdego, kto zastanawia się, jak dodawać komentarze do package.json, oto Twoja odpowiedź: stackoverflow.com/questions/14221579/ ...
Caleb
github.com/joyent/node/issues/6960 facet z węzłów mówi, że Windows jest obywatelem pierwszej klasy. Oni powiedzieli. Ale zamknęli problem i nic nie naprawiono. Szczęśliwi użytkownicy systemu Windows.
vee
38

Nie sądzę, aby było jakieś świetne rozwiązanie, biorąc pod uwagę twoje ograniczenia, ale oto kilka rzeczy, które mogą pomóc.

  • Spróbuj użyć, npm dedupeaby zoptymalizować hierarchię katalogów, co może skrócić niektóre ścieżki
  • Służy npm install --productiondo instalacji bez narzędzi programistycznych
  • Weź niektóre z tych głęboko zagnieżdżonych zależności (sugeruję tylko tyle, aby uniknąć problemu) i przenieś je do katalogu node_modules najwyższego poziomu. Po prostu śledź je, aby wiedzieć, które są twoimi prawdziwymi zależnościami i które stanowią obejście tego problemu.
  • LUB przenieś niektóre z tych głębokich zależności do najwyższego node_moduleskatalogu your_project/node_modules/pkg_with_deep_deps, który pozwoli im mieć wystarczająco krótkie ścieżki, ale nadal będą działać. Więc to będzie your_project/node_modules/pkg_with_deep_deps/node_modules.
    • Myślę, że requirepowinienem być w stanie znaleźć je poprawnie w czasie wykonywania. Musisz tylko jasno udokumentować, co ręcznie zmieniłeś, dlaczego to zrobiłeś i zachować swoje własne prawdziwe zależności dokładnie przedstawione wpackage.json

Oto dyskusja na githubie, która szczegółowo omawia ten problem.

Peter Lyons
źródło
Dzięki za wskazanie dedupe(w ogóle o tym nie wiedziałem) i --production( npm install -hnie pokazałem tej opcji)! Korzystanie z archiwum ZIP niestety nie wchodzi w grę, patrz komentarz powyżej.
Borek Bernard
9
Deduplikacja npm spowoduje tylko spłaszczenie „wspólnych” modułów do najniższej wspólnej lokalizacji w hierarchii. Nie wystarczająco dobre. Właściwe rozwiązanie pozwoliłoby „wymusić spłaszczenie” całej hierarchii i ewentualnie pozwolić zignorować katalogi test / doc. Alternatywą byłoby, gdyby węzeł obsługiwał odczytywanie modułów bezpośrednio z pliku tar.
MMind
3
Zgoda, jakiś rodzaj "binarnej" dystrybucji pakietów (ZIP, archiwum, cokolwiek) byłby bardzo przydatny.
Borek Bernard
11

Napisałem moduł węzła o nazwie „npm-flatten”, który spłaszcza twoje zależności tutaj: https://www.npmjs.org/package/npm-flatten

Jeśli szukasz dystrybucji, napisałem również pakiet NuGet, który zintegruje pełne środowisko node.js z projektem .NET tutaj: http://www.nuget.org/packages/NodeEnv/

Opinie byłyby mile widziane.

user3602171
źródło
To zadziałało dla nas. Jeszcze lepsze wyniki uzyskaliśmy, gdy najpierw uruchomiliśmy dedup nmp.
Shaun Rowan
1

Pomogło mi mapowanie dysku lokalnego do mojego folderu Node.js:

użycie sieci n: \ nazwa komputera \ c $ \ użytkownicy \ moja nazwa \ dokumenty \ node.js / persistent: tak

Przed: c: \ użytkownicy \ moja nazwa \ dokumenty \ node.js \ nazwa projektu (45 znaków) Po: n: \ nazwa projektu (14 znaków, czyli o 31 znaków mniej)

W wielu przypadkach pozwalało to na zainstalowanie niektórych modułów.

Powiem, że właśnie dzisiaj ponownie odkryłem ten problem, kiedy próbowałem wykonać kopię zapasową całego mojego kodu na dysku USB.

„C: \ Users \ myname \ Documents \ Node.js \ angular-phonecat \ node_modules \ karma \ node_modules \ chokidar \ node_modules \ anymatch \ node_modules \ micromatch \ node_modules \ regex-cache \ node_modules \ benchmarked \ node-reader_modules \ node_modules \ extension-shallow \ benchmark \ fixtures jest za długa. "

Nawet gdy próbowałem wykonać ich kopię zapasową za pomocą litery N: dysku, w niektórych przypadkach nadal nie udawało się to z powodu długości ścieżek, ale wystarczyło, aby naprawić powyższy.

Michael Blankenship
źródło
1

1) Podczas kompilacji wydania można zapobiec skanowaniu tych plików / folderów przez program Visual Studio, ustawiając właściwości folderu jako folder ukryty (WYSTARCZY ustaw go na node_modules). Źródła: http://issues.umbraco.org/issue/U4-6219#comment=67-19103

2) Możesz wykluczyć pliki lub foldery, które są publikowane podczas pakowania, dołączając następujący węzeł XML do pliku CsProject.

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
  ...
  <OutputPath>bin\</OutputPath>
   <NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
  <ExcludeFilesFromDeployment>File1.aspx;File2.aspx</ExcludeFilesFromDeployment>
  <ExcludeFoldersFromDeployment>Folder1;Folder2</ExcludeFoldersFromDeployment>
</PropertyGroup>
David Chelliah
źródło
1

Znalazłem jedno rozwiązanie z Microsoft node.js wytycznych .

  • Zacznij od krótkiej ścieżki (np. C: \ src)
  • > npm install -g rimraf usuń pliki, które przekraczają max_path
  • > npm dedupe przenosi zduplikowane pakiety na najwyższy poziom
  • > npm install -g flatten-packages przenosi wszystkie pakiety na najwyższy poziom, ale może powodować problemy z wersjonowaniem
  • Uaktualnij, do npm@3którego próbuje się dokonaćnode_modules hierarchię folderów maksymalnie płaską.
    • Dostarczane z Node v5
    • Lub… > npm install –g npm-windows-upgrade
zangw
źródło
0

To nie jest właściwe rozwiązanie, raczej obejście, gdy się spieszysz, ale możesz użyć 7-Zip, aby spakować folder, przenieść spakowany plik i rozpakować go bez żadnego problemu.

Wykorzystaliśmy to rozwiązanie do wdrożenia aplikacji Node.js, w której nie można było przeprowadzić czystej instalacji npm.

Jason
źródło
Tak. To jest to, co robię za każdym razem, gdy muszę zainstalować mangustę. Ma w sobie natywny kod i mam wiele / nowszych wersji programu Visual Studio = niepowodzenie. Mogłem po prostu otworzyć VS, wprowadzić każdy uszkodzony plik .sln i odtworzyć go. Ale po prostu łatwiej jest po prostu XCOPY na całym moim zestawie folderów node_modules \ mongoose w razie potrzeby (oczywiście oglądając wersje).
Michael Blankenship