Webpack - zarządzanie modułami
Dzielimy pliki Javascript i CSS na moduły
Dzielenie kodu na moduły pozwala odseparować niezwiązane ze sobą części, co wpływa na porządek w projekcie. Gdy pracujemy z danym elementem strony nie chcemy przecież przekopywać się przez masę innych niezwiązanych ze sobą funkcji w celu znalezienia tego, czego szukamy. No dobrze, podzielimy nasz kod, np. na 15 plików JS i 10 plików CSS, ale czy to oznacza, że teraz powinniśmy załączyć 15 tagów <script> i 10 tagów <link> w pliku HTML? Oczywiście, że nie! Duża ilość osobno podpiętych plików znacząco wpływa na wydajność ładowania naszej aplikacji, gdyż każdy plik to osobne żądanie HTTP. Tu z pomocą przychodzi nam Webpack.
Webpack
Webpack - jest to narzędzie, które pozwoli nam spiąć wszystkie nasze moduły w jeden plik, tzw. bundle. Dzięki temu później będziemy mogli załączyć na stronę pojedynczy plik, co jest dużo bardziej wydajnym rozwiązaniem. Ponadto, Webpack może dla nas zoptymalizować wielkość plików czy nawet przetranspilować kod ES6 używając Babel i wiele więcej. Wszystko dzięki dodatkowym loaderom i pluginom.
Instalacja
Webpack dodajemy do naszych dev-zależności poleceniem:
Konfiguracja
Konfiguracja Webpacka przechowywana jest domyślnie w pliku webpack.config.js, a jej podstawowa wersja wygląda tak:
- entry - para nazwa - ścieżka, gdzie podajemy nazwę oraz wskazujemy plik, który łączy moduły.
- path - folder, do którego będą trafiać nasze paczki.
- filename - nazwa paczki, która powstanie z nazwy w entry i “.bundle.js”
Lączenie plików
Aby Webpack wiedział jakie pliki ma połączyć, musimy to podać w plikach zadeklarowanych w entry. Służy do tego metoda:
Dla przykładu:
Zamiast scieżki można też podać nazwę pakietu zainstalowanego przez npm, tak jak w przykładzie: require('jquery');
Webpack + Babel
Teraz pozostało dla ułatwienia stworzyć sobie skrypt, który będzie uruchamiał webpacka. W tym celu do pliku package.json dodajemy linię:
i teraz możemy stworzyć nasze pliki polecenim:
Aby stworzyć zoptymalizowaną wersję, musimy do skryptu przekazać parametr -p. Parametry do skryptów poprzedzamy –, a więc w ten sposób:
Jeżeli używasz ES6, to operacja ta nie powiedzie się, gdyż optymalizacja nie działa z ES6. Problem ten rozwiąże Babel.
Babel transpiluje kod ES6 na zrozumiały dla starszych przeglądarek. Standardowo instalujemy go za pomocą npm:
Ponadto musimy dodać go do konfiguracji w webpack.config.js
CSS
Pliki JS mamy z głowy, ale co z CSS? Do nich musimy pobrać kolejny loader, gdyż Webpack domyślnie wspiera tylko JS. A więc:
Następnie dodajemy loadery oraz plik CSS do webpack.config.js:
Pliki możemy łączyć standardowo za pomocą funkcji @import, np. plik main.css może wyglądać tak:
Jednak Webpack nie łączy tą metoda wszystkich importów w jeden plik. Dodaje go inline do DOM, co ma kilka wad. Wydajność jest lepsza tylko dla małych ilości CSS. Uniemożliwia to ładowanie naszych plików CSS do cache przeglądarki, bo poprostu ich nie ma! Wtedy, za każdym odświeżeniem strony wszystko musi być załadowane od nowa, co w przypadku dużych ilości styli nie jest zbyt optymalne. Rozwiązaniem jest plugin ExtractTextPlugin, dzięki któremu połączymy pliki CSS w jeden i będziemy go mogli tradycyjnie załączyć w HTML. Instalacja:
Następnie w pliku webpack.config.js dodajemy stałą:
Oraz podmieniamy loadery CSS i definiujemy nowy plugin:
Teraz, dzięki Webpackowi, możemy dzielić do woli pliki JS i CSS, a ostatecznie załączymy ich tzw. bundle.
Jeśli w twoich plikach, które łączysz, wystepują importy czcionek (np. w Bootstrap) Webpack wyrzuci błędy. Można to rozwiązać z pomocą url-loader, jednak warto je pominąć, gdyż często załączane jest kilka formatów (woff, woff2, eot, ttf). Url-loader przetworzyłby je wszystkie, co skutkowałoby ogromnym plikiem CSS. Normalnie, przeglądarka wybiera tylko jeden odpowiedni, a resztę pomija. Dlatego lepiej skorzystać z opcji dla css-loader, która wyłącza przetwarzanie @import url(), ale normalnie działa z @import:
Będziemy musieli wtedy inaczej łączyć pliki CSS (bez url()), np:
EDIT:
Okazuje się, że jeśli z podaną konfiguracją używamy kilka "entries" na raz (zarówno pliki JS jak i CSS) powstają duplikaty dla plików CSS w wersji JS. Aby to obejść musimy nieco zmienić konfigurację webpack.config.js :