Przeniesienie projektu Node z npm na pnpm bez zakłócenia pracy zespołu
npm kontra pnpm pod względem układu plików, zależności widmowych i plików lockfile, a następnie migracja zespołu Node.js przy użyciu pnpm import, opcji only-allow oraz pola packageManager z ustalonym wartością.
Źródła: Switching from npm to pnpm
Menedżery pakietów decydują o tym, w jaki sposób zależności są zapisywane na dysku, który plik blokujący komitować oraz jak restrykcyjne są zasady importu w przypadku wystąpienia problemów. Dla wielu projektów Node domyślnym rozwiązaniem pozostaje npm. Zespoły zarządzające kilkoma repozytoriami muszą również radzić sobie z ciągłym napływem ostrzeżeń bezpieczeństwa wymagających podniesienia wersji. Dependabot może automatycznie uruchomić niektóre z tych aktualizacji; inne wymagają ręcznej interwencji, ponieważ rozwiązania transytywne się kolidują lub dlatego, że ostatecznym rozwiązaniem jest całkowita zamiana pakietu.
Mniej więcej w tym samym czasie GitHub dostosował Dependabota tak, aby prośby o zmianę wersji niesiące ze sobą zagrożenia bezpieczeństwa musiały czekać trzy dni przed uruchomieniem aktualizacji. Ta zmiana polityki jest w większości niezależna od wyboru menedżera pakietów, ale pokazuje, jak głośne stały się automatyczne aktualizacje.
Tymczasem incydenty w łańcuchu dostaw nadal pojawiają się w wiadomościach prasowych. Zainfekowane lub podatne na ataki pliki znajdują się w aplikacjach, które korzystają zarówno z zestawów ikon, narzędzi autoryzacji, jak i innych utilitów tokenowych, więc zasięg zagrożenia rośnie z każdym pośrednim elementem łańcucha. Ostrzeżenia bezpieczeństwa rzadko przychodzą pojedynczo – laptop, który używa kilku takich usług, może otrzymać informacje dotyczące parserów pośrednich, pakietów interfejsu użytkownika oraz narzędzi autoryzacji w tym samym tygodniu. Automatyczne boty pomagają, gdy problem ma charakter techniczny; mają trudności jednak, gdy nowsza wersja zmienia API lub gdy dwie zależności nie zgadzają się co do wspólnego źródła danych. W takich sytuacjach sensowne jest zastanowienie się, czy sam instalator może zmniejszyć ryzyko – poprzez odrzucanie niepotrzebnych zależności, udostępnianie treści na dysku tak, by audyty widziały tylko jedną kopię danej wersji, oraz spowalnianie nowych publikacji, dopóki ekosystem nie przeanalizuje sytuacji.
Jedną z często powtarzanych sugestii jest przechodzenie z npm na pnpm: podobne codzienne polecenia, bardziej rygorystyczny model instalacji oraz zazwyczaj mniejsze obciążenie dysku. Poniższe sekcje porównują te dwa narzędzia, nie stwierdzając jednoznacznego zwycięzcy – dostarczają jedynie wystarczająco dużo informacji, by ocenić, czy taka zmiana jest warta kosztów migracji.
Ogólne informacje o npm / pnpm
npm
- Jest domyślnym menedżerem pakietów w Node.js.
- Kontroluje instalację zależności oraz skrypty w pliku
package.json. - Często używane polecenia to
npm install(instalacja z pliku lock/manifest),npm install(dodanie zależności),npm runoraznpm uninstall. - Tworzy plik
package-lock.json. - Pakiety są przechowywane w katalogu
node_modules.
npm dostarcza również npx, który uruchamia pakiet bez dodawania go do projektu ani instalowania go globalnie. Narzędzia typu scaffolding, takie jak npx create-vite@latest project-name, pobierają je tymczasowo, wykonują i nie ingerują w plik package.json. Różnica w stosunku do npm install jest celowa: jednorazowe wykonanie w porównaniu z trwałą zależnością.
pnpm
- Menedżer pakietów od firmy trzeciej, który pełni tę samą funkcję — zarządzanie zależnościami i skryptami — ale w inny sposób przechowuje dane na dysku.
- Znane polecenia mają podobne nazwy:
pnpm install,pnpm add <name>,pnpm run <script>,pnpm remove <name>. - Zazwyczaj zajmuje mniej miejsca na dysku i szybciej kończy instalacje, przechowując każdą wersję tylko raz.
- Ogranicza importy do tego, co określono w pliku
package.json.
pnpm-lock.yaml zamiast package-lock.json.Uruchamiający narzędzie jednorazowe, analogiczne do npx, to pnpm dlx – przydatne na przykład podczas tworzenia struktury projektu za pomocą create-vite. Wiele generatorów akceptuje również pnpm create. Dla plików binarnych już obecnych w node_modules, lokalnym narzędziem do ich uruchamiania jest pnpm exec.
Zalety i wady pnpm
Kompromisy są równie ważne jak hasła reklamowe:
- npm kopiuje pakiety do
node_moduleskażdego projektu, co powoduje duplikację treści pomiędzy repozytoriami; pnpm przechowuje jedną kopię z adresem treści dla każdej wersji i umożliwia do niej odwoływanie się z projektów. - Taka struktura zazwyczaj zmniejsza zużycie dysku i przyspiesza powtarzane instalacje.
- Historicznie bardziej płaska struktura rozwiązywania problemów przez npm może sprawić, że kod będzie wymagał pakietu, który nigdy nie został deklarowany; pnpm odrzuca takie niespodziewane importy, co zmniejsza powierzchnię ataku.
- Późniejsze wdrażanie zupełnie nowych wersji przez pnpm zmniejsza szansę natychmiastowego pobrania zainfekowanej wersji oprogramowania.
- Npm z biegiem czasu nabrał podobnych funkcji, ale kilka z nich pozostaje opcjonalnych, a nie domyślnych.
- Pnpm wymaga oddzielnego kroku instalacji; npm jest dostępny razem z Node.
- Stare pluginy, które zakładają strukturę npm, mogą wymagać modyfikacji pod bardziej rygorystyczne zasady łączenia plików w pnpm.
- Memoria ruchowa zespołu nadal skłania się ku npm, więc adaptacja może wymagać krótkiego okresu dostosowania.
Różnice w układzie dysku są szybko widoczne na maszynach CI, które słabo cacheują pliki node_modules, oraz na komputerach programistów, którzy mają zainstalowane kilkanaście aplikacji. Przechowywanie adresowane treścią oznacza, że drugi i trzeci projekt wymagający lodash@4.x tworzą głównie linki zamiast kolejnego pełnego drzewa plików. Surowsza widoczność zależności wpływa również na proces debugowania: gdy import się nie udaje z powodu braku deklaracji pakietu, błąd pojawia się już podczas instalacji lub sprawdzania typów, zamiast być zaskoczeniem w czasie wykonywania kodu spowodowanym tym, że inny pakiet przypadkowo go zaimportował.
Przejście na pnpm
Minimalna globalna instalacja wygląda tak:
// Installation command (once)
npm install -g pnpm
// Usage
pnpm install
pnpm add [package name]
pnpm run [script name]
pnpm remove [package name]
Po pierwszej udanej instalacji w projekcie należy oczekiwać istnienia pliku pnpm-lock.yaml obok (a z czasem zamiast) pliku package-lock.json.
Istnieją inne metody instalacji, w tym skrypty samodzielne; dokumentacja dotycząca instalacji pnpm je wymienia.
Migracja istniejącego projektu npm zazwyczaj oznacza usunięcie plików node_modules i package-lock.json, a następnie uruchomienie polecenia pnpm install. Większość aplikacji działa poprawnie; niestandardowe dodatki natywne lub starsze rozwiązania mogą wymagać jednorazowych korekt.
Aby zapisać wersje z istniejącego pliku lockfile, należy uruchomić polecenie pnpm import. Aby usunąć pozostałości po npm:
// For macOS/Linux/Git Bash:
rm -rf node_modules package-lock.json
// For Windows PowerShell:
rm -Recurse -Force node_modules, package-lock.json
Aby zapobiec przypadkowemu uruchomieniu npm install później, należy dodać zabezpieczenie preinstall:
"scripts": {
"preinstall": "npx only-allow pnpm"
}
Następnie należy dodać ten narzędzie jako zależność rozwojową:
pnpm add -D only-allow
Ustalenie dokładnej wersji interfejsu linii poleceń dla współpracowników odbywa się za pomocą pola packageManager (można zmienić ciąg wersji według potrzeb):
{
"packageManager": "pnpm@11.22.0"
}
To pin utrzymuje CI i laptopy przy jednej wersji CLI; pamiętaj, aby celowo je zaktualizować podczas aktualizacji przez zespół.
Sprawdź i zaktualizuj samodzielnie za pomocą:
pnpm --version
pnpm self-update
Jeśli samodzielna aktualizacja nie działa poprawnie, zainstaluj narzędzie globalnie za pomocą npm install -g pnpm i uruchom ponownie shell.
Po udanej zmianie powinieneś zobaczyć:
- Zniknięcie pliku
package-lock.json. - Obecność pliku
pnpm-lock.yaml. - Plik
package.jsonpozostaje niezmieniony, z wyjątkiem dodanych pinów lub skryptów. - Plik
node_moduleszostał przepisany przy użyciu narzędzia linkującego pnpm (lub utworzony na nowo poprzezpnpm install). - Polecenia codziennej pracy, które różnią się głównie nazwą narzędzia na początku.
- Zapусki jednorazowe za pomocą
pnpm dlxzamiast wcześniej używanegonpx.
Oficjalna dokumentacja pozostaje źródłem informacji na temat skomplikowanych przypadków; powyższe notatki wystarczą do oceny migracji i przeprowadzenia rutynowego przełączenia.
Traktuj pierwszy przemigrowany repozytorium jako próbę generalną: uruchom zestaw testów, upewnij się, że kompilacje z użyciem Dockera nadal działają, oraz sprawdź, czy wszystkie natywne dodatki kompilują się przy nowym linkerze. Gdy ten proces stanie się prosty, stosowanie tego samego ustawienia packageManager oraz zasady only-allow we wszystkich powiązanych usługach zapewnia spójność całej infrastruktury. Jeśli jakiś stary narzędzie naprawdę nie może funkcjonować przy strukturze pnpm, lepiej je odizolować, zamiast rezygnować z bardziej rygorystycznych ustawień we wszystkich innych miejscach.
Literatura pokrewna
- Ustawienie frontendu React z Node, npm i Vite — Przyporządkowanie narzędzi w stylu Python do stacku React plus Vite: instalacja Node, ignorowanie foldera node_modules, tworzenie szkieletu przy użyciu Vite oraz uruchomienie lokalnego serwera rozwojowego.
- Redis poza cacheowaniem: sesje, limity przepustowości, kolejki i pub/sub w Node.js — Siedem wzorców wykorzystania Redis dla backendów w Node.js — cacheowanie z TTL, klucze OTP, limity przepustowości, zadania BullMQ, sesje, limity pub/sub oraz sytuacje, gdy nie należy używać Redis.
- Audyt SPF, DKIM i DMARC z Node.js z priorytetyzowanymi wynikami — Wywołanie API do audytu bezpieczeństwa e-maili z Node, prawidłowe obsługiwanie selektorów DKIM oraz przekształcenie wyników w uporządkowany plan naprawczy.