Uwaga! Ten wpis stracił już nieco na aktualności… Na szczęście dla Ciebie, udostępniłem już na blogu jego aktualizację i to nie w postaci jednego wpisu ale całej serii! Poniżej podaję linki do wszystkich odcinków serii na temat podstaw konfiguracji nowej wersji webpacka:

Ogólnie to nadal warto przeczytać poniższy wpis, ale potem lepiej zapoznać się z powyższymi wpisami!


W najbliższym czasie planuję tutaj na blogu przedstawić Wam wstęp do ReactJS. Uważam jednak, że zanim to nastąpi, warto poznać podstawy konfiguracji webpack. Narzędzie to jest praktycznie nieodzowne przy każdej aplikacji w React. Dlatego też dziś kilka słów na temat tego czym jest Webpack oraz jak go zainstalować i skonfigurować. Zapraszam!

Co to jest Webpack?

Webpack jest to “module bundler” co oznacza, że potrafi on spakować wiele różnych typów zasobów do jednego wynikowego zasobu. Na przykład jeśli posiadamy w naszym projekcie wiele modułów JavaScript, ale też pliki Sass, LESS, itp., webpack potrafi przekształcić je i zminifikować. Następnie wszystko razem umieścić w jednym pliku *.js. Zaletą takiego rozwiązania jest na pewno wydajność: jeden plik do pobrania z serwera to jedno do niego zapytanie.

Zapewne mógłbyś powiedzieć, że na rynku jest mnóstwo innych, podobnych narzędzi, po co więc nam, do cholery, jeszcze jedno? No cóż, webpack ma tę przewagę nad innymi tego typu narzędziami, że pozwala na dzielenie wynikowych plików na mniejsze kawałki (chunks). Takie kawałki mogą być ładowane na różnych podstronach naszej aplikacji w zależności od potrzeb. Wydaje mi się, że może to mieć spore znaczenie szczególnie w dużych projektach, gdzie mamy wiele różnych, rozbudowanych funkcjonalności, które nie koniecznie od siebie zależą. Nie jest przecież wówczas konieczne ładowanie wszystkiego na każdej podstronie aplikacji.

Podstawy konfiguracji Webpack - instalacja

No dobra, dość pitolenia! ;) Wiemy już co nieco czym jest narzędzie Webpack. Teraz przyszedł czas dowiedzieć się wyglądają podstawy konfiguracji Webpack. Na początek zacznijmy od jego instalacji. Najlepiej zrobić to za pomocą narzędzia NPM czyli Node Package Manager. Aby to zrobić należy wywołać w konsoli poniższą komendę (w zależności od systemu operacyjnego i konfiguracji, może być niezbędne użycie sudo):

npm install webpack -g

Po wykonaniu powyższej komendy, powinniśmy mieć Webpack zainstalowany globalnie. Kolejna rzecz to dodanie go do naszego projektu. Aby tego dokonać, należy najpierw przejść w konsoli do głównego katalogu projektu i dodać do niego plik package.json. Można to oczywiście zrobić ręcznie ale myślę, że lepiej wykorzystać do tego odpowiednią komendę NPM’a:

npm init

Po przebiciu się przez serię pytań zadawanych przez narzędzie init, nasz projekt jest skonfigurowany do instalowania w nim modułów NPM. Jeśli chcesz się upewnić, że rzeczywiście wszystko jest na miejscu, sprawdź czy plik package.json rzeczywiście pojawił się w głównym katalogu Twojego projektu.

Jeśli wszystko jest OK, to przyszła pora aby zainstalować Webpack w naszym projekcie:

npm install --save-dev webpack

Gotowe! Najwyższy więc czas aby zająć się konfiguracją Webpack!

Konfiguracja Webpack

Po pomyślnej instalacji Webpacka powinniśmy mieć w konsoli dostęp do komendy webpack. Ma ona kilka przydatnych opcji - poniżej te najbardziej użyteczne:

  • webpack – jednorazowo buduje pakiet wynikowy
  • webpack -p – buduje jednorazowo wraz z minifikacją
  • webpack --watch – buduje pakiet, a następnie czeka na przyszłe zmiany

Teraz, kiedy wiemy jak “odpalić” proces “bundlowania” (pakietowania?), sprawdźmy jak konfiguruje się Webpack. Aby to zrobić należy stworzyć kolejny plik w głównym katalogu naszego projektu - webpack.config.js. Poniżej jego przykładowa, praktycznie minimalna zawartość:

module.exports = {
  entry: './main.js',
  output: {
    path: __dirname + '/dist',
    filename: 'bundle.js'
  }
};

Powyższa konfiguracja zostanie odczytana przez komendę webpack za każdym razem gdy ją uruchomimy. Tak jak wspomniałem jest ona praktycznie minimalna tzn. że, musimy conajmniej określić nasz plik wejściowy (w tym przypadku main.js) oraz plik wyjściowy.

Plik main.js powinien być punktem wejściowym systemu modułów AMD lub CommonJS. Istnieje też możliwość skorzystania z ES6, na przykład za pomocą odpowiedniego “loadera” Babel’a - wtedy system modułów ES6 również będzie obsługiwany. Na temat “loaderów” napiszę za moment.

Ale wróćmy do pliku main.js. Kiedy wywołamy komendę webpack, zagląda ona do tego pliku i odczytuje wszystkie jego zależne moduły. Następnie zaczyna rozwiązywać głębsze zależności aż do momentu gdy wie już o nich wszystko. Kolejny krok to odpowiednie “spakowanie” ich w odpowiedniej kolejności do pliku wynikowego (w naszym przykładzie bundle.js). Na koniec plik wynikowy umieszczany jest w docelowym katalogu (dist).

Poza łączeniem modułów, Webpack potrafi obsłużyć również różnego rodzaju statyczne zasoby takie jak arkusze stylów czy obrazki. Jeśli chcesz się dowiedzieć więcej na ten temat, zapraszam do zapoznania się z dokumentacją.

Loadery modułów

Skoro znamy już podstawy podstaw, czas pójść dalej i wziąć na tapetę koncepcję “loaderów” (ładowaczy?) modułów. Ogólnie rzecz biorąc, “module loaders” w Webpack to coś podobnego do pluginów w Gulp. Pozwalają nam one na dodawanie różnego rodzaju transformacji w trakcie trwania procesu “bundlowania”. Do wtyczek Gulp’a upodabnia je też to, że są one wpinane w “pipeline” dzięki czemu możemy wprowadzić łańcuch takich loaderów i zostaną one wykonane jako łańcuch wywołań.

Spójrzmy na prosty przykład użycia takich loaderów. Zanim jednak zaczniemy, musimy taki loader zainstalować. Do tego celu znów wystarczy użyć NPM:

npm install --save-dev babel-loader

Po zainstalowaniu loadera możemy przystąpić do konfiguracji Webpacka. Aby to zrobić, należy lekko zmodyfikować plik webpack.config.js:

module.exports = {
  entry: './main.js',
  output: {
    path: __dirname + '/dist',
    filename: 'bundle.js'
  },
  module: {
    loaders: [
      { test: /\.js$/, loader: 'babel-loader' }
    ]
  }
};

Tym razem, kiedy uruchomimy komendę webpack, oprócz standardowych transformacji związanych z łączeniem wszystkiego w jeden plik, wykonany zostanie też zdefiniowany powyżej babel-loader. Jak się być może domyślasz, jest on odpowiedzialny za “transpilację” kodu napisanego w ES6 na kod ES5, który będzie zrozumiały dla przeglądarki internetowej. Jak widzisz na powyższym przykładzie, do parametru loaders przekazujemy tablicę. Możliwe więc jest użycie więcej niż jednego loadera na raz. To bardzo częsty przypadek ponieważ zwykle, chcemy też na przykład dokonać transformacji styli napisanych z użyciem Sass do standardowego formatu CSS. Do tego też istnieją odpowiednie “module loadery”.

Dwa słowa o konfiguracji loadera

Konfiguracja samego loadera też jest dość prosta. Jak widzisz, w tablicy przypisywanej do właściwości loaders, wrzuca się obiekty konfigurujące poszczególne loadery. Obiekt taki powinien zazwyczaj zawierać co najmniej dwie właściwości: test oraz loader. Pierwszy z nich to regex pattern, który Webpack wykorzystuje do rozpoznania czy dany plik kwalifikuje się do “potraktowania” danym loaderem. Właściwość loader z kolei to zwykle po prostu jego nazwa. Czasami jednak dorzuca się do niej jeszcze jakieś dodatkowe parametry (w stringu). Oprócz tych dwóch właściwości zdarza się, że jakiś loader wymaga lub pozwala na przekazanie dodatkowych parametrów w formie właściwości. To już jednak jest sprawa specyficzna dla takiego loadera więc informacje na ten temat znajdziesz w jego dokumentacji.

Oczywiście tematem dzisiejszego wpisu są podstawy konfiguracji Webpack, prezentuję więc tylko najprostsze przykłady. Biblioteka dostępnych loaderów dla Webpack’a jest bardzo bogata -tutaj wyszczególniona została spora ich lista.

Podsumowanie

Jak widzicie, Webpack oferuje całkiem ciekawe możliwości. Wydaje się, że w wielu kwestiach jest w stanie zastąpić Gulp’a. Osobiście mogę potwierdzić tę opinię - pracowałem juz w kilku projektach, w których większość automatyzacji załatwiał Webpack. Oczywiście sam Webpack może nie wystarczyć ale wtedy z pomocą przychodzą skrypty NPM. Dzięki połączeniu tych dwóch narzędzi, jesteśmy w stanie zupełnie pozbyć się Gulp’a.

Jak już wspomniałem, dziś chciałem Wam przedstawić jedynie podstawy konfiguracji Webpack. Jeśli zajrzycie do dokumentacji tego projektu, znajdziecie tam znacznie więcej opcji konfiguracyjnych. Zachęcam do pogrzebania bo w ostatnim czasie Webpack staje się jednym z ważniejszych narzędzie w web developmencie.