Strona główna / Artykuły

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ą.

Wydawca: REACTAPP.TOP6 min czytania1317 słów

Ź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 run oraz npm 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.
  • Używa pliku pnpm-lock.yaml zamiast package-lock.json.
  • Stosuje surowsze domyślne ustawienia dla nowo opublikowanych wersji (na przykład opóźniając ich przyjęcie).
  • 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_modules każ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.json pozostaje niezmieniony, z wyjątkiem dodanych pinów lub skryptów.
    • Plik node_modules został przepisany przy użyciu narzędzia linkującego pnpm (lub utworzony na nowo poprzez pnpm install).
    • Polecenia codziennej pracy, które różnią się głównie nazwą narzędzia na początku.
    • Zapусki jednorazowe za pomocą pnpm dlx zamiast wcześniej używanego npx.

    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

  • Master Playwright GitHub Actions YAML do przeprowadzania testów CI — Przeczytaj kompletny opis workflow Playwright GitHub Actions: od wyzwalaczy, zadań, pobierania plików, konfiguracji Node, npm ci, przeglądarek, testów po generowanie raportów.
  • Driftr: utrzymywany menedżer wersji Node oparty na shimach po zatrzymaniu Volty — Zastąp ciche workflow Volta shimami w języku Go, ustawieniami projektowymi oraz optymalizacją pnpm shared-store, która zapobiega duplikowaniu plików node_modules w każdym repozytorium.