Ścieżki plików systemu Windows Node npm są zbyt długie, aby można było zainstalować pakiety

89

Sytuacja

Chcę używać gulp i powiązanych łańcuchów narzędzi front-end w środowiskach programistycznych hostowanych przez system Windows. Uderzam w ścianę, próbując użyć wtyczek gulp, takich jak Browser-Sync, ponieważ wykres folderu node_modules rozszerza się, przez co ścieżki plików systemu Windows są zbyt długie, aby skopiować pliki. Chciałbym mieć pragmatyczne podejście do rozwiązywania tego problemu teraz w systemie Windows, niezależnie od tego, co społeczność Node może zapewnić lub nie, aby poprawić użyteczność npm w systemie Windows w przyszłości.

2 pytania

  1. Czy istnieje przepływ pracy npm dla systemu Windows, który działa tak, jak powinien? „uruchom polecenie i zainstaluj pliki” (np. porównywalne z npm na OSX, npm na Linuksie, ruby ​​gems lub nawet nuget) Nie chcę bawić się kilkoma ręcznymi edycjami plików, linkami symbolicznymi itp. za każdym razem, gdy używam npm w systemie Windows.

  2. Czy istnieje dobrze udokumentowany, stabilny przepływ pracy Cygwin dla wykonywania npm i węzłów w celu obejścia ograniczeń ścieżek do plików interfejsu API systemu Windows?

Krwawe szczegóły wymienione poniżej ...

Ogólny problem

  • Uruchamianie instalacji npm ze standardowego wiersza polecenia systemu Windows kończy się niepowodzeniem w przypadku głęboko zagnieżdżonych hierarchii modułów node_modules.
  • Według wątku repozytorium Joyent na github, jest to uznany problem, bez łatwych do zaakceptowania obejść dla programistów w środowiskach skoncentrowanych na systemie Windows. ( Naprawdę? )
  • Jądro NT obsługuje ścieżki do plików o długości do 32767 znaków.
  • Wartość MAXPATH interfejsu Windows API jest ograniczona do 260 znaków.
  • Windows API obsługuje operacje na plikach dla wszystkich głównych powłok Windows i nie tylko: Explorer, CMD, Powershell, MYSgit bash itp. ( MS naprawdę? Jak długo istnieje NTFS? )
  • Cygwin obsługuje długie ścieżki plików, ale npm.cmd nie działa po wyjęciu z pudełka z powodu formatowania crlf. Wypróbowałem transformację DOS2Unix na npm, aby działała z Cygwin, ale wydaje się, że są z tym inne problemy.

Mój obecny hack

  • Utwórz folder „n” jako obszar przemieszczania w katalogu głównym C: \, ponieważ skraca to ścieżkę do folderu.
  • Uruchom npm w folderze „n”, aby zainstalować moduły na wszystko, czego potrzebuję.
  • Uruchom Cygwin i użyj cp, aby skopiować folder node_modules do projektu docelowego.
  • Wypłucz i powtórz, gdy zmieniają się zależności lub gdy muszę uruchomić nowy projekt.

Inne niesmaczne obejścia

Łącza symboliczne mogą służyć do skracania ścieżek plików, ale są to nieznośne hacki. Wraz z rozwojem ekosystemu npm zagnieżdżone łańcuchy zależności staną się zbyt długie i to obejście stanie się bezużyteczne.

Dodanie WSZYSTKICH zależności do pliku package.json folderu głównego było wspomniane w jednym wątku, z którym się spotkałem. Chociaż takie podejście spowoduje spłaszczenie struktury folderów i zapobiegnie ładowaniu zduplikowanych modułów, to obejście wydaje się nienaturalne. Zabija również użyteczność, trwałość i produktywność npm, ponieważ musisz bawić się plikami i folderami po instalacji ręcznie lub za pomocą niektórych hackerskich skryptów. Podejście to jest również narażone na taki sam los, jaki może ostatecznie ponieść podejście linków symbolicznych.

Allan McLemore
źródło
Prawie myślałem, że mam to rozwiązane. Mam Cygwina współpracującego z npm, uruchamiając dos2unix util na następujących 2 plikach: npm.cmd i npm
Allan McLemore
Ograniczenia ścieżki interfejsu API systemu Windows powodują, że npm nie nadaje się do użytku, ponieważ niektóre moduły npm używają programu Visual Studio do kompilowania plików. To jest błąd, który otrzymuję, gdy I npm Browser-Sync: C: \ Program Files (x86) \ MSBuild \ Microsoft.Cpp \ v4.0 \ V120 \ Microsoft.CppBuild.targets (301,5): błąd MS B3491: Could nie zapisuj wierszy do pliku „Release \ obj \ validation \ validation.tlog \ validation.lastbuilds tate”. Podana ścieżka, nazwa pliku lub oba te elementy są za długie. W pełni kwalifikowana nazwa pliku musi mieć mniej niż 260 znaków, a nazwa katalogu musi mieć mniej niż 248 znaków.
Allan McLemore
Mogę mieć podejście "taffy-pulling", aby załadować moduły węzłów za pomocą npm w systemie Windows. Obejmuje kilka rund: npm install, npm dedupe, npm shrink i rm -r node_modules. Powtarzanie tego wydaje się w pewnym stopniu upraszczać długie ścieżki plików, ale jest to trochę tak, jak ciągnięcie za tęffy (np. Nie kończone, dopóki nie skończysz). Czy ktoś to skodyfikował lub napisał zautomatyzowane narzędzie, aby uczynić to bardziej pod klucz?
Allan McLemore
Mówiąc o „hacky scripts”, napisałem taki, którego nie uważam za STRASZNIE hakerski. Stworzyłem narzędzie o nazwie fenestrate, którego możesz użyć do programowego spłaszczenia struktury katalogów modułów po instalacji. Możesz zainstalować go jako globalny punkt postinstalacyjny npm.
zetlen
2
@yoneal Do użytku osobistego i aby szybko zacząć, fenestrate powinien rekurencyjnie przechodzić po folderze node_modules, więc nie powinno być potrzeby uruchamiania go ręcznie w przypadku głębokich zależności. Jednak byłoby wspaniale rozwidlić te zależności - myślę, że wiele rozwidlonych modułów z prostymi konfiguracjami fenestrate wyśle ​​świetną wiadomość do opiekunów npm.
zetlen

Odpowiedzi:

58

Problem z głęboko zagnieżdżonymi folderami w systemie Windows został w większości rozwiązany począwszy od wersji npm 3.x.

Według npm:

.npm @ 3 sprawia, że ​​instalacja jest „maksymalnie płaska”, podnosząc wszystko, co możliwe, do najwyższych modułów node_modules. Oznacza to, że zagnieżdżanie występuje tylko w przypadku konfliktów i jako takie, drzewa nigdy nie powinny być bardzo głębokie. W związku z tym ograniczenie długości ścieżki systemu Windows nie powinno występować.

Właśnie zainstalowałem npm 3.1.0i wypróbowałem go na pakiecie, który generował przerażający The specified path, file name, or both are too longbłąd.

Problem zniknął.

Najnowsze kompilacje npm można pobrać stąd: wydania npm

biofraktal
źródło
4
Odniosłem również sukces z aktualizacją npm 3.x na komputerze z systemem Windows. Bezwstydna wtyczka: napisałem artykuł o npm 3 na Windows triplet.fi/blog/…
Tx3
21

Windows 8.1 i 10 mają opcję zwiększenia limitu ścieżki Win32:

  • Otwórz edytor zasad grupy (naciśnij Windows+ Ri wpisz gpedit.msci naciśnij Enter)
  • Przejdź do następującego katalogu: Local Computer Policy\Computer Configuration\Administrative Templates\System\Filesystem
  • Kliknij dwukrotnie opcję Włącz długie ścieżki Win32 i włącz ją.

wprowadź opis obrazu tutaj

Marcelo Mason
źródło
opcja nie była dostępna dla mnie i fwiw, zaktualizowałem z win 7 pro, więc to jest możliwa przyczyna
Evan Morrison
@EvanMorrison „System plików \ ​​NTFS \ Włącz długie ścieżki NTFS” została zmieniona na „System plików \ ​​Włącz długie ścieżki Win32” w późniejszych kompilacjach win10. Zaktualizowałem odpowiedź na przyszłość.
Marcelo Mason
1
jakikolwiek pomysł na Win Server 2012 R2
sairfan
12

To jest obejście problemu.

Istnieje kilka modułów węzłów, które spłaszczają twoje zależności.
Linki są tutaj:

To, co robią te moduły, można również wykonać ręcznie. Jest to jedyne prawdziwe rozwiązanie, jakie istnieje w tej chwili, tj. Aby wszystkie moduły były na jednym poziomie, wymagając od siebie nawzajem, zamiast głęboko zagnieżdżonych prywatnych kopii ich zależności.

Amol M Kulkarni
źródło
10
Uważam, że spłaszczone-pakiety są dobrze udokumentowane i łatwe w użyciu.
StriplingWarrior
3

Allan -

Na podstawie problemu na Githubie, z którym łączysz się,

npm domyślnie doda deduplikację w czasie instalacji. Jest to znacznie bardziej wykonalne niż zmiana systemu modułów Node, ale nadal nie jest to trywialne i wymaga wielu przeróbek niektórych od dawna zakorzenionych wzorców.

Jest to (wreszcie) obecnie w pracach w npm, pod nazwą multi-stage-installi jest przeznaczone npm@3. npmkierownik ds. rozwoju Forrest Norvell zamierza spędzić trochę czasu w systemie Windows w nowym roku, więc prosimy o tworzenie problemów związanych z systemem Windows w npmnarzędziu do śledzenia problemów < https://github.com/npm/npm/issues >

Sam Mikes
źródło
3

Mam ten sam problem. Spłaszczanie zależności nie jest kompletnym rozwiązaniem, ponieważ możesz używać modułów zależnych od różnych wersji tego samego zależnego modułu. Odkryłem, że moduł gulp-run przestał działać po spłaszczeniu (podejrzewam, że jest to związane z założeniami modułu dotyczącymi katalogów bin / .bin). Kurcze!

Jest wiele dyskusji na temat problemu, ale nie widać rozwiązania: https://github.com/joyent/node/issues/6960

https://github.com/npm/npm/issues/3697

Rozwiązaniem, które działa dla mnie, jest ręczne dodawanie zależności, których mój projekt nie potrzebuje.

Jeśli chcesz określić, które pakiety powodują problemy, uważam, że PathLengthChecker jest całkiem przydatny. Po prostu wyodrębnij plik EXE i uruchom GUI lub aplikację wiersza poleceń. Innym sposobem, w jaki odkryłem problem, jest próba kompilacji w programie Visual Studio, ale kończy się to niepowodzeniem bez wskazania, która nazwa katalogu jest za długa.

Oto przykład mojego obejścia w wierszu poleceń:

mkdir c:\reallylongdirectorywillbreakinwindows
cd c:\reallylongdirectorywillbreakinwindows
npm init
npm install --save-dev grunt-bower-task
PathLengthChecker.exe RootDirectory="C:\reallylongdirectorywillbreakinwindows" MinLength=260

Wróciłem:

261: C: \ reallylongdirectorywillbreakinwindows \ node_modules \ grunt-bower-task \ node_modules \ bower \ node_modules \ update-notifier \ node_modules \ najnowsza-wersja \ node_modules \ package-json \ no de_modules \ register-url \ node_modules \ npmconfodules config-chain \ readme.markdown

[wycinek - było ich 12]

Zgodnie z poleceniem npm ls :

└─┬ grunt-bower-task@0.4.0
  ├── async@0.1.22
  ├─┬ bower@1.3.12
  │ ├─┬ update-notifier@0.2.0
  │ │ ├─┬ latest-version@0.2.0
  │ │ │ └─┬ package-json@0.2.0
  │ │ │   └─┬ registry-url@0.1.1
  │ │ │     └─┬ npmconf@2.1.1
  │ │ │       ├─┬ once@1.3.1
  │ │ │       │ └── wrappy@1.0.1

Przejdźmy do npmconf - jest to kontener dla wszystkich plików o zbyt dużej długości, które powodują problemy. Potrzebujemy npmconf 2.1.1.

npm install --save-dev npmconf@2.1.1
(now delete the node_modules directory - you may have to use Windows Explorer if you can't do it with rmdir /s)
npm install
PathLengthChecker.exe RootDirectory="C:\reallylongdirectorywillbreakinwindows" MinLength=260

Brak wyników - wszystkie pliki mieszczą się w granicach!

Oczywistym zastrzeżeniem jest to, że działa tylko raz na pakiet - zależności na różnych wersjach tego samego modułu nie mogą być instalowane na poziomie root_modules, ponieważ węzeł nie uwzględnia wersji w strukturze katalogów.

To obejście nie jest idealne, ale rozwiązuje moje główne cele związane z pracą węzła w systemie Windows, a ponieważ rozdzielczość jest właściwa w pliku package.json, obejście działa dla innych programistów i buduje serwery bez ręcznego lub globalnego zamieszania.

Stefan Mohr
źródło
2

Jeśli zgadzasz się na globalną instalację, może to być obejście:

Możesz dostosować ścieżkę, w której npm instaluje moduły globalne, do czegoś bardzo krótkiego (zwykle jest to c:\users\\{username}\AppData\Roaming\npm\npm_modules:), co już zajmuje dużo znaków.

Aby go dostosować, zobacz tutaj: Zmień domyślny globalny katalog instalacyjny dla modułów node.js w systemie Windows?

Jeśli dostosujesz go, np. c:\n\W niektórych przypadkach, może to rozwiązać problem.

gwildu
źródło
1

To ostatecznie naprawiło to dla mnie ...

Po zainstalowaniu gulp i otrzymaniu błędów uruchom ... gulp

Gdy zobaczysz, że pakiet kończy się niepowodzeniem, zainstaluj go ręcznie z --no-bin-link.

sudo npm install {package} --no-bin-link

Gdzie {pakiet} to pakiet, z którym występują problemy.

Po tym wszystkim otrzymałem błąd we wtyczce „gulp-notify”. Wiadomość: not found: notify-send.

Było to spowodowane problemem z wtyczką w Vagrant. Możesz wyłączyć powiadomienia.

export DISABLE_NOTIFIER=true;

Lub zainstaluj wtyczkę za pomocą Vagrant .

Powodzenia… Spędziłem nad tym dużo czasu, nawet po zastosowaniu się do zaleceń wielu ludzi.

Brandon

user3310182
źródło
0

W oknach:

  1. Korzystając z eksploratora Windows, przejdź do folderu współdzielonego włóczęgi (przy okazji używam scotchbox) np. C:\scotchbox/public/gulpProject
  2. W pasku adresu folderu wpisz cmdi naciśnijEnter
  3. Wykonaj instalację łykiem npm install
Justis Matotoka
źródło
1
Unikaj kopiowania i wklejania tej samej odpowiedzi . Zamiast tego należy oflagować jako duplikat. Ponadto nie przeklinaj w swoim poście.
Tunaki,
0

npm install --no-bin-link. Będziesz miał cały spłaszczony node_modules

kenberkeley
źródło