Все для создания и продвижения сайтов

Верстка, программирование, SEO

Webpack 5: создание базовой конфигурации

Рассмотрим, как собрать простую конфигурацию на Webpack 5 для разработки, ничего сложного не будем делать, для старта будет достаточно.

Для начала создадим пустую папку для проекта и инициализируем проект npm. И установим webpack, webpack-cli (инструмент, используемый для запуска webpack из командной строки) и webpack-dev-server (для создания сервера для удобной разработки):

npm init -y
npm install webpack webpack-cli webpack-dev-server --D

Теперь создадим папку src, в ней мы будет разрабатывать наше приложение, также создадим файл index.js в этой папке. Именно этот файл станет точкой входа сборки нашего приложения.

Далее создадим папку dist, в неё будет компилироваться наше выходное приложение. (содержимое папки можно вытащить и запустить в любом месте). Внутри папки создадим файл index.html, это будет статический файл, который будет подключать наш сбилденный скрипт.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Webpack 5</title>
</head>
<body>
    <!-- Сюда подключается сбилденный файл из webpack -->
    <script src="bundle.js"></script>
</body>
</html>

Теперь осталось создать лишь конфиг для вебпак, 5 версия WebPack позволяет не использовать его, но лучше все таки его создать, ничего сложного в нем нет на начальном этапе, давайте его добавим и разберемся немного в нем. Создаем в корне файл webpack.config.js со следующим кодом:

const path = require('path');

module.exports = {
    context: path.resolve(__dirname, 'src'),
    entry: './index.js',
    mode: 'development',
    devtool: 'inline-source-map',
    devServer: {
        /** Будет запускать сервер на localhost:8080 в этой папке*/
        contentBase: './dist',
    },
    watch: true,
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
    },
    module: {
        rules: [
            /** Babel **/
            {
                test: /\.m?js$/,
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env']
                    }
                }
                // npm install babel-loader @babel/core @babel/preset-env -D
            },
            /** CSS */
            {
                test: /\.css$/i,
                use: ['style-loader', 'css-loader'],
                // npm i style-loader css-loader -D
            },
            /** SCSS/SAAS */
            {
                test: /\.s[ac]ss$/i,
                use: [
                    // Creates `style` nodes from JS strings
                    "style-loader",
                    // Translates CSS into CommonJS
                    "css-loader",
                    // Compiles Sass to CSS
                    "sass-loader",
                ],
                // npm i style-loader css-loader sass sass-loader -D
            },
            /** Картинки */
            {
                test: /\.(png|svg|jpg|jpeg|gif)$/i,
                type: 'asset/resource',
            },
            /** Шрифты */
            {
                test: /\.(woff|woff2|eot|ttf|otf)$/i,
                type: 'asset/resource',
            },
            /** Файлы CSV */
            {
                test: /\.(csv|tsv)$/i,
                use: ['csv-loader'],
                // npm i csv-loader -D
            },
            /** Файлы XML */
            {
                test: /\.xml$/i,
                use: ['xml-loader'],
                // npm i xml-loader -D 
            },
        ],
    },
};

Теперь разберемся с параметрами:

  • context - указываем контекст, т.е. папку, которую будет обрабатывать webpack (в большинстве случаев у всех так)
  • entry - точка входа, указываем файл, с которого начнется обработка webpack (в папке, которую мы указали в context, т.е. - src/)
  • mode - можно указать одно из значение: none, development, production, в зависимости от этого, вебпак выбирает разные режимы работы, быстрота - для production, удобность разработки - development, не нужны никакие действия, то указываем none.
  • devtool - указываем inline-source-map, для составления карты, которые позволяет удобнее дебажить по файлам проекта, а не в сбилденном проекте в браузере
  • devServer - для удобной разработки будет создаваться сервер с watcher, который при изменение любого файла перезагрузит страницу автоматом, в режиме dev
  • watch - возможность отслеживание изменения файлов
  • output - указываем, куда будет билдится наш проект, указываем папку и название файла
  • modules - вебпак умеет работать не совсеми файлами из коробки, для работы со стилями, csv, xml и прочим его нужно подружить, для этого необходимо правило, где мы указываем в test - расширения файла по маске и в use указываем loaders, которые будут их обрабатывать, для работы loaders нужно установить соответствующие пакеты.

Также мы подключили babel, для перевода кода на JS с нового синтаксиса в старый (необходим для работы во всех браузерах)

Конфиг есть, теперь для удобства, нам нужны скрипты для удобного запуска проекте через console или IDE.

Добавим три скрипта в свойство scripts: build, watch, start.

{
  "name": "webpack 5",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "build": "webpack",
    "watch": "webpack --watch",
    "start": "webpack serve --open"
  },
  "devDependencies": {
    "@babel/core": "^7.13.14",
    "@babel/preset-env": "^7.13.12",
    "babel-loader": "^8.2.2",
    "css-loader": "^5.2.0",
    "sass": "^1.32.8",
    "sass-loader": "^11.0.1",
    "style-loader": "^2.0.0",
    "webpack": "^5.28.0",
    "webpack-cli": "^4.5.0",
    "webpack-dev-server": "^3.11.2"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
}
  • build - простая сборка проекта, использается для запуска на prod. Генерирует файлы в папке dist
  • watch - тоже самое, что и build, только в этом случае, при каждом изменение файлов в проекте будет происходить пересборка проекта
  • start - запускает сервер для нашего проекта и открывает страницу в браузере, требуется для удобной разработки, плюсом ещё у нас будет обновляться страничка при изменении любых файлов.

Вот в принципе и все, что нужно для старта. Дополнительно покажу, как стоит писать проект и подключать файлы.

src/index.js

// Подключение картинки
import Icon from './icon.png';

// подключение стилей
import './style.scss';

function component() {
    const element = document.createElement('div');

    element.innerHTML = 'Hello Webpack 5';
    element.classList.add('hello');

    // Пример использования картинки
    const myIcon = new Image();
    myIcon.src = Icon;

    element.appendChild(myIcon);

    return element;
}

document.body.appendChild(component());

src/style.css

$body-color: green;

// Подключения шрифтов
@font-face {
  font-family: 'MyFont';
  src: url('./my-font.woff2') format('woff2'),
  url('./my-font.woff') format('woff');
  font-weight: 600;
  font-style: normal;
}

body {
  color: $body-color;
  // подключения картинок
  background: url('./icon.png');
}

В итоге у нас получается такая структура файлов:

|– /dist
|  |- index.html
|– /src
|  |  |– index.js
|  |  |– style.css
|  |  |– icon.png
|  |  |– my-font.woff
|  |  |– my-font.woff2
|- package.json
|- webpack.config.js

В принципе этого достаточно для начала, но можно немного улучшить наш проект

Сделаем так, чтобы нам не пришлось в ручную править файл dist/index.html, а сделать так, чтобы он собирался сам.

Для этого нам понадобиться HtmlWebpackPlugin, давайте установим и добавим его.

npm install html-webpack-plugin -D

Затем подключим и добавим его в webpack.config.js.

Также для удобства в output добавим параметр clean, для удаления сбилденных файлов, после новой сборки, чтобы не копился мусор, а также будем генерить новый имена для файлов, плагин сам поймет и подключит все файлы внутри index.html как надо.

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

module.exports = {
    // .....................
     output: {
        filename: '[name].[contenthash].js', // динамичное и уникальное имя файла
        path: path.resolve(__dirname, 'dist'),
        clean: true, // для очистки папки dist при новом билде
    },
    plugins: [
        new HtmlWebpackPlugin({
            title: 'Наш заголовок страницы',
        }),
    ],
    // .....................

Теперь все содержимое папки dist - генерируемое, мы можем очистить полностью папку и сгенерить заного.

Все этого вам должно хватить на начальном этапе сборки, на будущее вы можете подключать новые плагины, лоадеры для новых файлов, разбить конфиг для прода и дева. И так далее.

Выделите опечатку и нажмите Ctrl + Enter, чтобы отправить сообщение об ошибке.