npm - jak działa

npm, czyli Node Package Manager, to menedżer pakietów dla środowiska Node.js. Można go porównać do sklepu z aplikacjami, ale dla programistów JavaScript. Ułatwia zarządzanie bibliotekami i narzędziami (pakietami), których potrzebujesz w swoich projektach Node.js i JavaScript.

Najważniejsze elementy i funkcje npm:

  1. npm CLI (Command Line Interface) - Interfejs linii poleceń:

    • To główny sposób, w jaki Ty, jako programista, komunikujesz się z npmem. Używasz komend npm w terminalu (wierszu poleceń) do wykonywania różnych operacji.

    • Przykłady komend npm:

      • npm install - instaluje pakiet (bibliotekę, narzędzie).

      • npm uninstall - odinstalowuje pakiet.

      • npm update - aktualizuje pakiet do najnowszej wersji.

      • npm run - uruchamia skrypty zdefiniowane w package.json.

      • npm init - inicjalizuje nowy projekt Node.js i tworzy package.json.

      • npm start, npm test, npm build - to standardowe skrypty często używane w projektach.

      • npm publish - publikuje Twój własny pakiet do rejestru npm (dla innych programistów).

      • npm audit - skanuje projekt pod kątem luk bezpieczeństwa w zależnościach.

      • npm cache clean --force - czyści cache npm (pamięć podręczną).

  2. Rejestr npm (npm registry):

    • To ogromna, publiczna baza danych (ogromny "sklep") z pakietami JavaScript. Jest to centrum ekosystemu npm.

    • Gdy wykonujesz komendę npm install , npm pobiera pakiet z tego rejestru (domyślnie z registry.npmjs.org).

    • W rejestrze znajdziesz ogromną ilość pakietów: biblioteki ułatwiające tworzenie stron internetowych, frameworki (jak React, Vue, Angular, SvelteKit), narzędzia do testowania, buildowania, i wiele, wiele innych.

    • Oprócz publicznego rejestru, istnieją też prywatne rejestry npm dla firm i organizacji, które chcą hostować pakiety tylko dla swojego wewnętrznego użytku.

  3. package.json - Plik konfiguracji projektu:

    • To plik JSON w głównym folderze Twojego projektu Node.js. Jest to serce npm w Twoim projekcie.

    • Opisuje projekt: Zawiera informacje o Twoim projekcie, takie jak nazwa, wersja, opis, autor.

    • Listuje zależności: Najważniejsze, wymienia wszystkie pakiety (biblioteki, narzędzia), od których zależy Twój projekt.

      • dependencies: Lista pakietów, które są niezbędne do działania Twojej aplikacji w środowisku produkcyjnym. Np. biblioteki UI, frameworki, biblioteki do obsługi bazy danych.

      • devDependencies: Lista pakietów, które są potrzebne tylko w trakcie developmentu, ale nie są wymagane w produkcyjnej wersji aplikacji. Np. narzędzia do testowania, buildowania, linting (sprawdzania jakości kodu), formatowania kodu.

    • Skrypty (scripts): Definiuje skrypty, które możesz uruchamiać za pomocą npm run . Standardowe skrypty to np. start, dev, build, test, ale możesz definiować własne. Skrypty te automatyzują typowe zadania w projekcie.

    • Przykładowy package.json (uproszczony):

       

{
  "name": "moj-projekt",
  "version": "1.0.0",
  "description": "Opis mojego projektu",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "dev": "nodemon index.js",
    "build": "webpack",
    "test": "jest"
  },
  "dependencies": {
    "express": "^4.18.2",
    "lodash": "^4.17.21"
  },
  "devDependencies": {
    "nodemon": "^3.0.3",
    "webpack": "^5.90.0",
    "jest": "^29.7.0"
  },
  "author": "Twoje Imię",
  "license": "MIT"
}


  1. node_modules - Folder z zależnościami:

    • Gdy uruchamiasz npm install, npm pobiera pakiety wymienione w package.json i ich zależności (bo pakiety też mogą zależeć od innych pakietów).

    • Wszystkie te pakiety są instalowane w folderze node_modules w głównym folderze Twojego projektu.

    • node_modules może być bardzo duży, bo pakiety często mają wiele zależności, a te zależności - kolejne zależności. To jest normalne.

    • Folder node_modules jest zazwyczaj ignorowany w systemach kontroli wersji (np. Git) i nie jest wgrywany na serwer produkcyjny. W produkcji wystarczy mieć package.json i uruchomić npm install na serwerze, żeby odtworzyć node_modules.

    • Struktura node_modules jest zagnieżdżona, pakiety są organizowane w drzewo zależności. Nowsze wersje npm (i inne menedżery pakietów jak Yarn i pnpm) starają się "spłaszczać" tę strukturę, żeby zoptymalizować wykorzystanie miejsca i wydajność.

  2. package-lock.json (lub pnpm-lock.yaml, yarn.lock) - Plik blokady wersji:

    • Gdy instalujesz pakiety, npm (od wersji 5) automatycznie generuje plik package-lock.json (lub pnpm-lock.yaml dla pnpm, yarn.lock dla Yarn).

    • Ten plik jest bardzo ważny dla zapewnienia powtarzalności buildów i stabilności projektu.

    • Blokuje dokładne wersje zależności: package-lock.json zapisuje dokładne wersje wszystkich zainstalowanych pakietów i ich zależności, włącznie z ich zagnieżdżonymi zależnościami. Dzięki temu, jeśli Ty lub ktoś inny uruchomi npm install w przyszłości, zostaną zainstalowane DOKŁADNIE TE SAME WERSJE pakietów, jakie były użyte, gdy plik package-lock.json został wygenerowany.

    • Zapobiega problemom z aktualizacjami: Bez package-lock.json, npm install instalowałby najnowsze wersje pakietów zgodne z zakresami wersji zdefiniowanymi w package.json (np. "express": "^4.18.2" oznacza "dowolna wersja 4.18.2 lub nowsza z gałęzi 4.18.x"). To może prowadzić do problemów, jeśli nowsza wersja jakiegoś pakietu wprowadzi zmiany powodujące błędy w Twoim projekcie. package-lock.json eliminuje to ryzyko, gwarantując spójne środowisko zależności.

    • Zawsze commituj package-lock.json (lub odpowiednik) do systemu kontroli wersji. To kluczowe dla pracy zespołowej i stabilnych buildów.

Podstawowy workflow pracy z npm w projekcie:

  1. Inicjalizacja projektu: W nowym folderze projektu uruchom npm init -y (lub npm init, jeśli chcesz interaktywnie odpowiadać na pytania). To stworzy plik package.json z podstawowymi informacjami.

  2. Instalacja pakietów: Użyj npm install .

    • npm install - zainstaluje pakiet i doda go do dependencies w package.json.

    • npm install --save-dev lub npm install -D - zainstaluje pakiet jako devDependencies.

    • npm install (bez nazwy pakietu) - zainstaluje wszystkie pakiety wymienione w dependencies i devDependencies w package.json (na podstawie package-lock.json, jeśli istnieje).

  3. Uruchamianie skryptów: Użyj npm run , np. npm run dev, npm run build, npm run test, npm run start.

  4. Aktualizacja pakietów: Użyj npm update . Zwykle lepiej jest świadomie aktualizować pakiety i testować projekt po aktualizacji, żeby uniknąć niespodziewanych problemów. Możesz też chcieć używać narzędzi do automatycznego aktualizowania zależności, ale z rozwagą.

  5. Odinstalowywanie pakietów: Użyj npm uninstall .

Alternatywy dla npm:

  • Yarn: Inny popularny menedżer pakietów dla JavaScript, stworzony przez Facebook, Google, Exponent i Tilde. Yarn był popularny ze względu na szybkość i deterministyczne instalacje (już w pierwszej wersji). Nowsze wersje npm też stały się szybsze i bardziej deterministyczne. Yarn nadal jest używany i ma swoje zalety.

  • pnpm (performant npm): Menedżer pakietów, który zyskuje popularność ze względu na swoją wydajność i oszczędność miejsca na dysku. pnpm używa sprytnych linków symbolicznych i współdzielenia pakietów, żeby zminimalizować duplikację i przyspieszyć instalację. Jest uważany za bardzo szybki i efektywny.

W skrócie: npm jest kluczowym narzędziem w ekosystemie Node.js i JavaScript. Ułatwia zarządzanie zależnościami, automatyzację zadań i udostępnianie kodu. Zrozumienie, jak działa npm, jest podstawą do efektywnego tworzenia aplikacji Node.js i nowoczesnych aplikacji frontendowych.