Podstawy pracy z npm - okładka

Co to jest npm – podstawy pracy z npm

W tymp wpisie dowiesz się, co to jest npm, do czego Ci się mozę przydać oraz jak go wykorzystać w praktyce.

Co to jest npm?

Npm jest menadżerem zależności (dependencies) dla języka JavaScript. Do opublikowania zależności w npm jedyne co jest konieczne to założenie konta na npmjs.org. W zasobach npm znaleźć można zarówno zależności tworzone i rozwijane przez organizacje jak i paczki utrzymywane przez społeczność.

Instalacja

Instalacja npm na lokalnej maszynie jest banalna. Należy odwiedzić stronę nodejs.org i pobrać Node.js. Wraz z Node.js dystrybuowany jest npm jako domyślny menedżer pakietów. Po zakończeniu procesu instalacji, w wierszu poleceń warto wykonać polecenia: node -v oraz npm -v. Zwracają one aktualnie zainstalowane wersje Node.js oraz npm.

 

npm - nowy projekt

 

Tworzenie nowego projektu

Aby rozocząć rozwijanie projektu z wykorzystaniem zewnętrznych zależności należy utworzyć projekt. Głównym plikem w projekcie jest package.json.  Aby stworzyć nowy projekt można skorzystać z polecenia npm init. Można oczywiście również stworzyć plik package.json ręcznie. Po wywołaniu omawianego polecenia należy podać nazwę projektu, wersję, opis, entry point, komendę do testów, link do repozytorium, słowa kluczowe oraz typl licencji. W rezultacie wyświetlony zostanie podgląd, a konfigurator zapyta się czy wszystko jest wpisane poprawnie. Alternatywą jest wykrozystanie flagi --yes, która sprawia, że tworzony jest plik z domyślnymi parametrami.

Po zatwierdzeniu zmian wprowadzonych do konfiguratora w folderze z projektem zostaje stworzony plik package.json. Powinien on wyglądać mniej więcej tak:


{
  "name": "example-project",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Dominik Szczepaniak",
  "license": "MIT"
}

Co ciekawe, znajduje się tu pole z autorem, którego wcześniej nie podałem. Część z danych, które dla rozwijanych projektów będą takie same można ustawić ustawić poprzez ustawienie globalenej konfiguracji npm. Jako globalne dane można ustawić: autora, email, stronę www oraz licencja. Omawiany rezultat można osiągnąć poprzez wywołanie następujących poleceń:


npm config set init.author.name "Dominik Szczepaniak"
npm config set init.author.email [email protected]
npm config set init.author.url https://devszczepaniak.pl
npm config set init.license MIT

Instalacja zależności

Kluczowym zagadnieniem pracy z npm są zależności. Pakiety/zależności to packzi z kodem, które można pobrać i wykorzystać w projekcie w ramach licencji jaka obowiązuje dla danej zależności. W celu instalacji zależności należy wywołać polecenie npm install, a po nim nazwa paczki, bądź paczek. W przypadku gdy nie zostanie podana żadna nazwa, zostaną zainstalowane wszystkie zależności jakie znajdują się w package.json w danej lokalizacji.

Istnieje też możliwość skorzystania ze skróconej wersji polecenia – słowo install zastępujemy literą i. Następnie przez odpowiednie flagi możemy wywoływać pożądane efekty i zależności. Pełnia możliwości polecenia npm install została opisana w dokumentacji npm.

Zależności mogą być instalowane na kilka sposobów. Pierwszy z nich to globalna instalacja zależności. Oznacza to że taka paczka będzie dostępna globalnie, czyli w każdym projekcie. Wykonujemy to poprzez flagę --global lub skróconą wersję -g. Ten sposób instalowania paczek zdecydowanie nie jest polecany dla zależności wykorzystywany bezpośrednio w projekcie. Należy pamiętać, że sam projekt nie zawiera wtedy żadnej informacji o tej zależności. Jeżeli projekt zostanie uruchomiony na innej maszynie, to w przypadku wykorzystania zależności zainstalowanych globalnie projekt może nie działać poprawnie. Ten sposób instalacji rekomendowałbym dla zależności, które są wykorzystywane jako narzędzia pomocnicze do pracy z projektem tj. http-server czy npm-check-updates.

Drugi sposób to instalowanie zależności z flagą --save, bądź skróconą wersją -S. Powoduje to dodanie zależności do obiektu dependencies. W tym obiekcie przechowywane są definicje dla zależności wykorzystywanych w wersji produkcyjnej naszej aplikacji. Każda zależność definiowana jest jako para wartości – nazwa zależności i jej wersja.

Trzecią opcją jest skorzystanie z flagi --save-dev lub skróconej wersji -D, co oznacza, że paczka zostanie zainstalowana jako zależność developerska. Takie zależności przecowywane są w obiekcie devDependencies. Zależności developerskie, to takie któe wykorzystywane są podczas pracy nad projektem lecz nie znajdują się w produkcyjnej wersji aplikacji. Przykładowe zależności developerskie to wszelkiedo rodzaju bundlery, test runnery, lintery, etc.

npm magazyn z paczkami

Wersjonowanie

Najczęściej spotytkanym formatem wersjonowania paczek jest format major.minor.patch. Taki format dzieli wersję na trzy części:

  • Major – aktualizacja tej części wersji wskazuje, że w zależności zaszły zmiany niekompatybilne względem poprzedniej wersji.
  • Minor – do zależności dodane zostały nowe funkcjonalności, kompatybilne względem poprzedniej wersji.
  • Patch – wersja zawiera poprawki z zachowaniem kompatybilności wstecznej.

Taki sposób wersjonowania nazywany jest wersjonowaniem semantycznym (semantic versioning). Więcej o wersjonowaniu semantycznym możesz przeczytać na semver.org.

Przy instalacji zależności można zdefiniować wersję do zainstalowania na kilka sposobów:

  • 1.0.0 – w takim wypadku zostanie zainstalowana dokładnie ta wersja paczki.
  • ~1.0.0 – zainstalowana zostanie zdefiniowana wersja lub wyższa jeśli istnieje wyższa wersja patch (np. 1.0.2).
  • ^1.0.0 – zainstalowana zostanie zdefiniowana wersja lub wyższa jeśli istnieje wyższa wersja minor lub patch (np. 1.1.2).

Aktualizacja i usuwanie zależności

Zależności w projekcie można aktualizować poleceniem npm update. Alternatywnie można też wykorzystać zależność npm-check-updates, która pozwala na sprwadzenie czy istnieje nowsza wersja dla zainstalowanych zależności.

Usuwanie paczek odbywa się za pomocą polecenia npm uninstall. Tutaj również możemy skorzystać z flag --save--save-dev i ich skróconych alternatyw. Oczywiście można też usunąć zależność ręcznie z pliku package.json.

Lokalizacja zależności

Zainstalowane zależności zlokalizowane są w folderze node_modules. Zazwyczaj jest to największy i najcięższy folder w naszym projekcie. Zawartości folderu node_modules nie umieszczamy ani na serwerze produkcyjnym, ani w repozytorium. Nie przejmuj się też rozmiarem tego folderu. Potrafi on mieć rozmiary kilkuset MB, a czasem nawet kilku GB. Istnieją rozwiązania takie jak pnpm, które pozwalają optymalizować przestrzeń zajmowaną przez node_modules poprzez mechanizmy linkowania i reużywania paczek.

Polecenia

W pliku package.json istnieje możliwość definiowania poleceń. Dzięki temu za pomocą jednej komendy możliwe jest wykonanie całego szeregu poleceń. Spójrz na przykład:


{
  "name": "example-project",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "webpack-dev-server --mode development --progress --hot --open",
    "build": "webpack --mode production --progress"
  },
  "author": "Dominik Szczepaniak",
  "license": "MIT",
  "dependecies": {
    "lodash": "^4.17.10"
  },
  "devDependecies": {
    "webpack": "^4.16.0",
    "webpack-cli": "^3.0.8",
    "webpack-dev-server": "^3.1.4"
  }
}

Zdefiniowane zostały dwa polecenia: devbuild. Jedno z nich powoduje uruchomienie servera developerskiego, zaś drugie powoduje zbudowanie projektu Polecenia używamy korzystając z polecenia npm run, a potem nazwa polecenia, np. npm run build.

Plik .npmrc

W pliku .npmrc przechowywana jest konfiguracja npm. Domyślną lokalizacją dla tego pliku jest katalog domowy ( C:\Users\Nazwa_usera w systemie Windows lub ~/ w systemach Unixowych). Po otwarciu pliku, ujrzeć można rezultat wcześniej przestawionych komend związanych z inicjalizacją projektu oraz inne opcje konfiguracyjne jeśli zostały uprzednio ustawione.

Jedną z istotniejszych możliwości konfiguracji jest zdefiniowanie domyślnego repozytorium dla paczek oraz przekazanie tokenów dostępowych. Są one konieczne w przypadku wykorzystywania prywatnych zależności oraz publikowania zależności w repozytorium npm. Konieczne tutaj będzie założenie konta w serwisie npmjs.com. Po założeniu konta zachęcam gorąco do włączenia uwierzytelniania dwuskładnikowego. Następnie należy wybrać zakładkę Access Tokens, oraz klikąć przycisk Generate New Token. W tym miejscu serwis zapyta nas o typ tokenu. Jeżeli token będzie wykorzystywany do publikowania paczek, to naley wybrać token typu Publish, w innym razie rekomenduję token Read-only. Odradzałbym wykorzsytanie tokenów Automatioch, chyba że jest to absolutnie konieczne. Tego typu tokeny nie wymagają wspomnianego już dwuskładnikowego uwierzytelniania, które oprócz dodatkowej warstwy bezpieczeństwa chroni także przed omyłkowym opublikowaniem paczki. Po wybraniu typu tokenu należy kliknąć Generate Token oraz koniecznie skopiować token, gdyż jego zawartość nie będzie wyświetlona nigdy więcej!

Po skopiowaniu tokenu, należy umieścić go w pliku .npmrc w następujący sposób:


//registry.npmjs.org/:_authToken=twój-access-token

Od teraz pobieranie prywatnych paczek oraz publikowanie paczek stoją przed nami otworem!

Publikowanie zależności

Publikowanie zależności jest banalnie proste. Pierwszym krokiem powinno być zdefiniowanie zawartości paczki. W pliku package.json należy dodać pole files, które będzie zawierało wszystkie pliki, które mają znaleźć się w opublikowanej paczce:


{
  "name": "example-project",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "files": [
    "/dist",
    "/assets"
  ],
  "scripts": {
    "dev": "webpack-dev-server --mode development --progress --hot --open",
    "build": "webpack --mode production --progress"
  },
  "author": "Dominik Szczepaniak",
  "license": "MIT",
  "dependecies": {
    "lodash": "^4.17.10"
  },
  "devDependecies": {
    "webpack": "^4.16.0",
    "webpack-cli": "^3.0.8",
    "webpack-dev-server": "^3.1.4"
  }
}

Następnie zachęcam do wywołania polecenia npm pack. W rezultacie zostanie utworzony plik z paczką. Dzięki temu możemy sprawdzić co ostatecznie znajdzie się w opublikowanej paczce. Zachęcam też do utworzenia pliku README.md, którego zawartość będzie pokazana na stronie paczki w serwisie npmjs.com. Jeśli wszystko się zgadza to można wywołać polecenie npm publish. W przypadku gdy włączono uwierzytelnianie dwuskładnikowe, konieczne będzie potwierdzenie operacji np. kodem z aplikacji 2FA.

Alternatywy dla npm

Zarówno dla repozytorium zależnosći jak i samego menadżera istnieją alternatywy. Alternatywne menadżery paczek, które możesz wykorzystać to:

  • yarn
  • pnpm

Z kolei alternatywami dla repozytorium paczek są:

  • GitHub Packages – pozwala zamieścić paczkę w obrębie konkretnego repozytorium (zarówno paczki publiczne jak i prywatne).
  • Verdaccio – jest to lokalne, prywatne repozytorium paczek. Może być przydatne, na przykład w przypadku gdy obawiamy się wycieku zawartości naszych zależności.

Myślę że w tym momencie jesteś gotów, aby stworzyć swój pierwszy projekt z wykorzystaniem! Jeśli masz jakieś uwagi, pytania lub wątpliwości napisz mi o tym w komentarzu!

Źródła i materiały dodatkowe

 

6 komentarzy do “Co to jest npm – podstawy pracy z npm”

  1. Dzięki wielkie za ten artykuł! 🙂 Będę do niego często wracał, aby odświeżyć podstawy.

  2. Warto tez wiedzieć jak działa npm link. Ja często robię małe statyczne strony, gdzie chętnie korzystam z preprocesorów CSS, Browserify i innych mniejszych pierdółek. Folder node_modules najmuje mi prawie 100mb. Niby nie duzo, ale po co za każdym razem to instalować. Zainstalowałem najczęściej używane paczki globalnie, a przy tworzeniu nowego projektu tylko do nich linkuje. Np:

    npm link gulp gulp-sass gulp-plumber gulp-autoprefixer gulp-remove-empty-lines bs-html-injector browser-sync gulp-html-partial gulp-changed

    Rach ciach i gotowe. Oczywiście zdaje sobie sprawę z tego, że czasami pożądana jest lokalna instalacja paczek, ale warto wiedzieć, że jest i taka opcja.

    Z innych przydatnych rzeczy to komenda, która listuje zainstalowane paczki npm w systemie (globalnie): npm list -g –depth=0

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.