W poprzedniej części trochę poszaleliśmy z opcjami w npm install
. Teraz skoncentrujmy się nad tym jak to można jeszcze bardziej zoptymalizować. Dla przypomnienia, chcemy zoptymalizować wykonywanie npm install
na build server, lub w miejscach gdzie często to wykonujemy dla określonego projektu. Część 1 skończyła się na zapytaniu:
npm install --no-optional --skip-installed --cache "D:\npm_cache" --cache-min 999999
Jeżeli posiadamy na serwerze dobry, szybki dysk twardy to, za pomocą małego tricku jesteśmy wstanie przyspieszyć nasz czas wykonania do kilku sekund (zależy od dysku).
W tym celu wykorzystamy trick pakowania i rozpakowywania – najlepiej bez kompresji, to ma być zabójczo szybkie a nie powolne.
Mianowicie kod nasz powinien odpowiadać następującemu scenariuszowi:
- Rozpakuj archiwum (jeżeli istnieje) do katalogu
node_modules
- Wykonaj czyszczenie (o tym zaraz)
- Zainstaluj paczki zgodnie z częścią 1
- Zapakuj
node_modules
i podmień lub stwórz plik z (1)
Koniec. Coś takiego jak będzie działało nam --skip-installed
, spowoduje widoczną poprawę prędkości instalowania paczek na dyskach SSD, na szybkich dyskach SSD to po prostu będzie miodzio.
Teraz, wspomniałem tutaj o czyszczeniu (krok 2). Warto zaznaczyć, że mając coś zipowane, może się okazać że posiadamy tam tego więcej niż aktualnie projekt potrzebuje (package.json
). Dlatego też warto wywalić z node_modules
wszystkie te paczki, które nie są zdefiniowane w package.json
. Można to wykonać za pomocą komendy prune
– wykanie jej jest banalnie proste :)
npm prune
Teraz, jeżeli to wszystko połączymy to jesteśmy wstanie stworzyć plik BAT
, który to za nas wszystko wykona i poda jeszcze czas wykonania. Poniżej przykładowy skrypt do wykorzystania na przykład w TeamCity.
@echo off set cache=%1 set cache7="%cache%\tc_cache.7z" set STARTTIME=%TIME% :: temporary system path at cmd startup to include 7zip set PATH=%PATH%;"%CD%\.tools" rem set PATH=%PATH%;"C:\Program Files\7-zip\" :: unpack zip cache echo extracting 7z node_modules cache call 7za x %cache7% -aos >nul: 2>nul :: remove packages if we have some that has changed (we have them in node_modules but not in package.jspn) echo pruning node_modules call npm prune echo installing node_modules no-optional;skip-installed;cache call npm install --no-optional --skip-installed --cache "%cache%" --cache-min 9999999 :: if there was an npm install error, propage it if %errorlevel% neq 0 exit /b %errorlevel% :: zip node_modules for cache purpose echo creating 7z node_modules cache for next time call 7za a -t7z -mx0 -mmt %cache7% node_modules >nul 2>nul echo cleaning artifacts (_nul file for whatever ^>nul is creating it) del _nul 2>nul set ENDTIME=%TIME% echo done %STARTTIME% - %ENDTIME%
W kolejnej części zobaczymy czy da się coś zrobić z tym dyskiem, by jednak to nie od niego zależało jak szybko to się będzie wykonywało :)
Optymalizacja npm install – Część 2
Dziękujemy za dodanie artykułu – Trackback z dotnetomaniak.pl
W moim projekcie jest 2MB źródeł (c#,js,scss, grafika) a po skonfigurowaniu gulpa do konwersji scss do css npm naściągał 30MB plików, 8170 plików i 2003 folderów. Do tego musiałem się nagimnastykować, żeby pasował node-sass (kombinacje install/uninstall, rebuild), bo nie chcałem z githubu ściągać binarki (licho wie jak z wirusami).
Pliki nie mogą być współdzielone, wszystko musi lecieć do node_modules. Zależności się powielają, w katalogach zalega mnóstwo plików (testy, źródła w C, js, yml). Spodziewałem się kilku plików a nie śmietnika.
Bower też nie lepszy – w nuget zdarzają się świeższe pakiety niż w bower (choćby underscore). Do tego doliczmy bezsens (podobnie jak npm) ściągania wszystkich plików dla jednego rozwiązania zamiast (tak jak to zrobiono w nuget) js z ew. css.
Sprawdziłem –no-optional i niestety to samo 40MB zajętego dysku/8177 plików, żeby być nowoczesnym i iść z duchem czasu (dla jednej funkcjonalności przy kompilowaniu!). Toż to 1/20 ilości plików w moim windows 10 :-D
Nie pomyślałeś nad rozwiązaniem ramdysk? Ram jest tani, pamięć szybka, zaś dyski SSD nie lubią małych plików, mają słabą wydajność przy takich plikach (widać to w testach IO4KB).
Spakowane archiwum node_modules na dany projekt można trzymać na ssd, zrobić z tego SHA1 i wynik zapisywać do repo. Przed buildem po SHA1 poszukać w magazynie (czy nawet redisie ;-) ) i rozpakować do ramu ew. cały zip trzymać w repo i rozpakowywać. Gdy zawartość node_modules sie nie zmienia, git nie robi kopii do nowych commitów tylko linkuje.
Całość dla mnie ponurego obrazu dopełnia słaba dokumentacja modułów, porzucanie projektów (np. takana – fajnie się zapowiadała, po windowsem problem, od roku na githubie brak akcji)
Moim zdaniem trzeba być ostrożnym z nodejs i npm.
Microsoft idzie w tę głupią modę, w VS2015 w WebEssentials wyrzucono cześć funkcjonalności, sugerując wykorzystanie gulpa, tylko, że jego obsługa lekko kuleje (np. w źródle nie wskazuje błedów w pliku źródłowym).
Moim zdaniem MS właśnie powinien włączyć stare WebEssentials do VS, kto to słyszał, żeby niezłe IDE także do JS domyślnie nie miało konwersji js/scss i innych operacji.
[…] że zamiast dawać komentarz do komentarza tomaszk-poz pod wpisem Optymalizacja npm install – Część 2 udostępnię tą odpowiedź jako post – ze […]
@tomaszk-pol
sorki, nie zmiescilem sie w polu komentarza, wiec dalem odp jako osoby post jest odp – w razie jakis problemow pisz :)
Comments are closed.