Kategoria:Webpack

Webpack 4 - loadery, pluginy i niestandardowa konfiguracja

  • Czas potrzebny na przeczytanie:4 minuty
  • Opublikowane:

Cześć 👋

W poprzednim wpisie poznałeś podstawy Webpacka, dzisiaj wykorzystamy tą wiedzę w praktycę i stworzymy konfigurację projektu.

Instalacja

Nie traćmy czasu na instalację, sklonujmy repo, które utworzyłem w poprzednim wpisie:

Wstępna konfiguracja

Stwórzmy teraz plik webpack.config.js:

Plik konfiguracyjny Webpacka to w ostateczności kod JavaScriptu, więc nic nie stoi nam na przeszkodzie, żeby zrobić w nim funkcję.

Pamiętacie jak podawaliśmy mode w poprzednim wpisie do package.json? Możemy, w tym samym pliku, utworzyć zmienną i w zależności od trybu np. ładować odpowiednie konfiguracje, ale do tego przejdźiemy za moment.

"scripts": {
    "webpack": "webpack",
    "dev": "npm run webpack -- --env.mode development --watch",
    "prod": "npm run webpack -- --env.mode production"
  },

Konfiguracja serwera

Zacznijmy od zainstalowania pluginu html-webpack-plugin.

Importujemy go w naszym pliku konfiguracyjnym, używając składni CommonJS, jako szablon dla wygenerowanego pliku dajemy przykładowy plik index.html znajdujący się w katalogu src/:

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = ({ mode }) => ({
  mode,
  output: {
    filename: 'bundle.js',
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
    }),
  ],
});

Zainstalujmy teraz serwer deweloperski i dodajmy odpowiedni skrypt do package.json:

"scripts": {
    "webpack-dev-server": "webpack-dev-server",
    "webpack": "webpack",
    "dev": "npm run webpack-dev-server -- --env.mode development --watch",
    "prod": "npm run webpack -- --env.mode production"
  },

Zbudujmy teraz nasz bundle i odpalmy serwer:

Rozdzielenie trybów

Może zdarzyć się tak, że będziesz potrzebował osobnej konfiguracji dla trybu prod i dev, w takim przypadku przychodzi nam z pomocą wtyczka webpack-merge:

Po zainstalowaniu stwórz folder w katalogu głównym o nazwie build-utils, a w nim webpack.production.js i webpack.development.js. Tutaj znajdą się nasze Webpackowe konfiguracje.

// webpack.production.js & webpack.development.js
module.exports = () => ({});

// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpackMerge = require('webpack-merge');

const modeConfig = (env) => require(`./build-utils/webpack.${env}`)(env);

module.exports = ({ mode } = { mode: 'production' }) =>
  webpackMerge(
    {
      mode,
      output: {
        filename: 'bundle.js',
      },
      plugins: [new HtmlWebpackPlugin()],
    },
    modeConfig(mode),
  );

Importujemy samą paczkę, tworzymy funkcję, która będzie zaciągała nasz plik na podstawie mode.

Używamy tutaj destrukturyzacji i początkowych wartości parametrów

Wykorzystajmy te możliwości i nadajmy inny output do trybu produkcyjnego.

Stworzyliśmy customową hashowaną ścieżkę dla pliku wyjściowego.

Sass

Jak możemy wykorzystać Webpacka z Sassem? Użyć loaderów!

Instalacja:

Stwórzmy teraz podstawowy plik z rozszerzeniem .scss:

Dodajmy style:

Do naszego webpack.development.js dopisujemy odpowiednie loadery:

module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: ["style-loader", "css-loader", "sass-loader"],
      },
    ],
  },

Teraz jeśli spróbujesz odpalić cokolwiek, prawdopodobnie zobaczysz błąd. Musimy jeszcze zaimportować plik css w naszym entry point, czyli w naszym przypadku w index.js. Dzieje się to dlatego, że Webpack każdy nasz plik traktuje jako moduł.

// index.js
import hello from './welcome';
import { multiplyByTwo } from './multiply';
import './main.scss';
console.log(hello, multiplyByTwo(2));

Okej, ale to nie będzie działać na produkcji, chcemy aby nasze moduły css trafiały nie do zbundlowanego pliku .js, lecz do osobnego pliku .css. Dodajmy więc odpowiedni plugin:

Na produkcji potrzebujemy dodać nasz plugin i zmienić style-loader na MiniCssExtractPlugin.loader:

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = () => ({
  output: {
    filename: '[chunkhash].js',
  },
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
      },
    ],
  },
  plugins: [new MiniCssExtractPlugin()],
});

Jeśli wszystko poszło po naszej myśli, powinieneś zobaczyć swój plik css w folderze dist/.

Babel

Na sam koniec, zainstalujmy Babela, który kompiluje współczesny JavaScript do starszych wersji.

Dodajmy odpowiednie reguły do webpack.production.js:

  {
        test: /\.m?js$/,
        exclude: /(node_modules)/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env"],
          },
        },
      },

Za pomocą wyrażeń regularnych sprawdzamy rozszerzenie pliku, dzięki exclude wykluczamy node_modules. Następnie załadowujemy odpowiedni loader i dodatkowe opcje.

Podsumowanie

Dzięki za wytrwanie do końca, to była podstawowa konfiguracja w moim wykonaniu, cały kod możecie znaleźć na githubie. Zachęcam do dalszego zgłębiania Webpacka, jest masa super pluginów, które możecie znaleźć w dokumentacji i dodać do swojego projektu.

Do usłyszenia!

Źródła

O autorze

Olaf Sulich

Olaf jest Frontend Developerem, blogerem i nosi rybacki kapelusz 🎩 Pisze o wszystkim co związane z frontendem, ale nie boi się backendu i designów 🦾 Ma głowę pełną pomysłów i nadzieję, że znajdziesz tutaj coś dla siebie!

Dołącz do społeczności!

Bo w programowaniu liczą się ludzie

Wchodzę