Сборщики Frontend и когда их применять

Привет, друзья! В этой статье мы разберем 3 самых популярных сборщика проектов для Frontend разработки. Вы узнаете их особенности, сценарии, в которых следует использовать определённый сборщик и поймете разницу между ними. Но перед тем как переходить к разбору самих сборщиков, поговорим о том, для чего эти сборщики нужны и как они упрощают нам жизнь.

Зачем нужны сборщики

В современной веб‑разработке существует масса полезных инструментов и технологий, которые упрощают нам процесс разработки и делают ее быстрой и удобной. Это могут быть:

  • Шаблонизаторы для HTML, чтобы разделять верстку на удобные шаблоны. Например Pug или Twig;

  • Препроцессоры CSS для упрощения написания стилей, такие как SASS или Less;

  • TypeScript, позволяющий строго типизировать данные;

  • Фреймворки, которые предоставляют наиболее удобные инструменты для разработки веб‑приложений и их постоянной поддержки, такие как React, Vue или Angular;

Здесь главное понимать, что ни один из этих инструментов по умолчанию не поддерживается браузером. То есть, если бы мы подключили созданные стили с использованием Sass, то это не привело бы ни к какому результату. Браузер знает только 3 основные технологии — HTML, CSS и JavaScript. Как же нам тогда скомпилировать свой код так, чтобы его понимал браузер?

Для этого каждый инструмент может предоставлять собственные методы обработки кода. Но если количество этих технологий увеличивается в одном проекте, то использовать эти методы по отдельности становится неудобно и этот процесс занимает неприлично много времени. Представим, что мы хотим создать проект, используя Pug, SCSS и TypeScript. В итоге у нас получилась бы приблизительно такая структура проекта:

/project
│── src/                   
│   ├── assets/            # Изображения, шрифты
│   ├── styles/            # SCSS-файлы
│   │   ├── main.scss      
│   │   ├── _variables.scss
│   ├── templates/         # Pug-шаблоны
│   │   ├── index.pug
│   │   ├── layout.pug
│   ├── scripts/           # TypeScript-код
│   │   ├── main.ts               
│── package.json           
│── tsconfig.json          # Конфигурация TypeScript
│── .eslintrc.js    

И теперь, чтобы собрать проект, необходимо преобразовать весь код в обычный HTML, CSS и JavaScript. Вот как это будет выглядеть:

  • Компиляция Pug в HTML
    npx pug src/templates/ -o dist/

  • Компиляция SCSS в CSS
    npx sass src/styles/main.scss dist/styles.css

  • Компиляция TypeScript в JavaScript
    npx tsc

Как видите, сборка проекта заняла собой 3 операции, а если мы захотим добавить другие инструменты, например Babel для поддержки старых браузеров и PostCSS для автопрефиксов, то команд станет вовсе 5!

b6be95862b0588ab9aef447198ab4d6c.png

Тут на помощь и приходят сборщики. Используя одну команду, мы можем скомпилировать сразу весь код, а также воспользоваться другими преимуществами, такими как локальный сервер, оптимизация кода и ресурсов, разные режимы сборки для разработки и продакшн.

Теперь, когда мы поняли насколько полезны могут быть сборщики, разберем их более подробно по отдельности.

Webpack. Мощный и гибкий

Тройку наших лидеров открывает Webpack. Он был создан в 2012 году немецким разработчиком Тобиасом Коппером.

Основная его цель — эффективное управление зависимостями и модулями в проектах на JavaScript, а также их оптимизация для использования в браузере. На тот момент существовало множество инструментов, но Webpack предложил революционный подход к сборке, основанный на графе зависимостей.

Особенности сборщика

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

  2. Tree Shaking
    Удаляет неиспользуемый код, тем самым оптимизируя его.

  3. Поддержка различных типов файлов
    Позволяет импортировать не только JavaScript, но и CSS, изображения, шрифты и другие ресурсы, используя загрузчики (лоадеры).

  4. Локальный сервер и HMR (Hot Module Replacement)
    Позволяет обновлять модули в браузере динамически без полной перезагрузки страницы, что ускоряет процесс разработки.

  5. Оптимизация ресурсов
    Позволяет минимизировать JavaScript, CSS, изображения и другие ресурсы для ускорения загрузки.

В каких проектах использовать?

Поскольку мы можем очень гибко настраивать нашу сборку, то и на создание её файла‑конфига может уходить немалое количество времени. Поэтому Webpack точно не подойдет для малых сайтов и веб‑приложений, для которых не планируется долговременная поддержка (Только если вы не хотите потренироваться в написании сборки). Давайте теперь взглянем на то, когда следует использовать Webpack:

  1. Средние и крупные сайты и веб‑приложения с большим количеством модулей и сложной логикой, где важно эффективно управлять зависимостями и ресурсами.

  2. Проекты с использованием JS‑фреймворков (React, Vue, Angular), так как Webpack интегрируется с их экосистемами и обеспечивает удобную разработку.

  3. Мультистраничные сайты и веб‑приложения (MPA), где важно эффективно организовать код‑сплиттинг, оптимизировать загрузку страниц и минимизировать дублирование кода.

Пример сборки

Рассмотрим пример сборки на Webpack для следующего стэка: Pug, SCSS, TypeScript.
После установки необходимых зависимостей мы получим примерно такую структуру проекта:

/project
│── /src                # Код, с которым мы работаем 
│   ├── /images
│   ├── /styles
│   │   ├── main.scss
│   ├── /scripts
│   │   ├── main.ts
│   ├── /templates
│   │   ├── index.pug
│   ├── index.pug
│── /dist                # Здесь будет лежать сборка
│── .gitignore
│── package.json
│── tsconfig.json
│── webpack.config.js    # Основной конфигурационный файл
│── webpack.dev.js       # Дополнительный настройки для разработки
│── webpack.prod.js      # Дополнительный настройки для продакшн

В основном конфигурационном файле будут находится общие настройки и для разработки, и для продакшн:

// webpack.config.js

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  // Точка входа. Главный скрипт, куда импортируются все модули
  entry: "./src/scripts/main.ts",

  // Файл, который получится после сборки
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist"),
    clean: true,
  },

  // Лоадеры для обработки ресурсов разных форматов (.pug, .scss, .ts и т.д.)
  module: {
    rules: [
      {
        test: /\.pug$/,
        use: ["pug-loader"],
      },
      {
        test: /\.scss$/,
        use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
      },
      {
        test: /\.ts$/,
        use: "ts-loader",
        exclude: /node_modules/,
      },
      {
        test: /\.(png|jpg|jpeg|gif|svg)$/,
        type: "asset",
        generator: {
          filename: "images/[name][ext]",
        },
      },
    ],
  },

  // Позволяет импортировать файлы, без указания их формата
  resolve: {
    extensions: [".ts", ".js"],
  },

  // Плагины для обработки CSS и генерации HTML
  plugins: [
    new MiniCssExtractPlugin({ filename: "styles.css" }),
    new HtmlWebpackPlugin({
      template: "./src/index.pug",
    }),
  ],
};

Теперь зададим параметры сборки для удобной разработки:

const { merge } = require("webpack-merge");
const common = require("./webpack.config");

// Совмещаем общую конфигурация с новой и подключаем локальный сервер
module.exports = merge(common({ production: false }), {
  mode: "development",
  devtool: "source-map",
  devServer: {
    static: "./dist",
    hot: true,
    open: true,
  },
});

Уже сейчас мы можем приступить к разработке, и сборка не будет занимать большое количество времени из‑за того, что мы не оптимизируем изображения и не минифицируем код в dev‑конфиге.

Осталось создать сборку для публикации нашего проекта в Интернете, максимально оптимизировав изображения и код:

const { merge } = require("webpack-merge");
const common = require("./webpack.config");
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");

module.exports = merge(common({ production: true }), {
  mode: "production",
  
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin(), // Минификация JS
      new CssMinimizerPlugin(), // Минификация CSS
    ],
  },

  // Оптимизация изображений
  plugins: [
    new ImageMinimizerPlugin({
      minimizer: {
        implementation: ImageMinimizerPlugin.squooshMinify,
      },
    }),
  ],
});

Сборка полностью готова! Чтобы ее запустить в нужном режиме достаточно добавить 2 скрипта в package.json:

"scripts": {
  "dev": "webpack serve --config webpack.dev.js",
  "build": "webpack --config webpack.prod.js"
}

Vite. Быстрый и современный

Следующим в нашем списке идёт Vite — один из новейших сборщиков, созданный в 2020 году Эваном Ю, который также является автором фреймворка Vue.js.

Vite был разработан как более быстрая и удобная альтернатива традиционным сборщикам. Он решает главную проблему Webpack — долгую инициализацию сборки — благодаря использованию ES‑модулей в браузере и молниеносной дев‑сборки на основе native ESM.

Особенности сборщика

  1. Мгновенный запуск сервера
    Благодаря использованию нативных ES‑модулей, Vite не требует полной предварительной сборки проекта — браузер загружает только то, что нужно, и именно тогда, когда нужно.

  2. Упрощённая конфигурация
    Из коробки работает с TypeScript, CSS, Vue, React и другими технологиями. В большинстве случаев не требует сложной настройки, но при этом поддерживает расширение через плагины.

  3. Быстрая горячая перезагрузка (HMR)
    Обновления при сохранении файлов практически мгновенны — даже в больших проектах, что делает разработку максимально комфортной.

  4. Оптимизированная сборка
    В режиме продакшн Vite использует Rollup под капотом для финальной сборки, что позволяет получить оптимизированный и минимизированный код.

В каких проектах использовать?

Vite идеально подходит для большинства современных проектов. Его стоит выбрать в следующих случаях:

  1. Малые и средние проекты, где важна скорость старта.

  2. Проекты на Vue, React, Svelte и других фреймворках, так как Vite официально поддерживает их через плагины и позволяет начать работу с минимальной настройкой конфигурации.

  3. SPA и MPA, где важны быстрые dev‑сборки и эффективная оптимизация при продакшне.

Пример сборки

Возьмем тот же самый стэк технологий, как и в Webpack: Pug, SCSS, TypeScript.

После установки зависимостей структура проекта будет следующей:

project/
├── src/
│   ├── index.pug
│   ├── main.ts
│   └── styles.scss
├── vite.config.ts     # Конфигурационный файл
├── tsconfig.json
└── package.json

Конфигурационный файл будет следующим:

import { defineConfig } from 'vite'
import pugPlugin from 'vite-plugin-pug'
import path from 'path'

export default defineConfig({
  root: 'src',
  
  // Настройки сборки для production
  build: {
    outDir: '../dist',
    emptyOutDir: true,
  },

  // Плагины
  plugins: [pugPlugin()],

  // Настраиваем алиасы для более удобных импортов
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
    },
  },

  // Настройки для работы с препроцессорами CSS
  css: {
    preprocessorOptions: {
      scss: {
        additionalData: `@import "@/styles/variables.scss";`
      }
    }
  }
})

Как можно заметить, сборка Vite занимает значительно меньше времени и настроек, по сравнению с Webpack, осталось лишь добавить npm‑скрипты:

"scripts": {
  "dev": "vite",
  "build": "vite build",
  "preview": "vite preview"
}

Parcel. Простой и удобный

Завершает тройку лидеров Parcel — сборщик, появившийся в 2017 году благодаря разработчику Девону Гомесу. Его главная идея — «zero config», то есть работа без необходимости настройки: просто укажи входной файл, и Parcel сам разберётся, что и как собирать.

Особенности сборщика

  1. Минимум настроек
    Parcel не требует конфигурации для большинства задач — поддержка TypeScript, JSX, CSS, изображений, JSON и многих других форматов включена по умолчанию.

  2. Встроенный дев‑сервер и HMR
    Parcel запускает локальный сервер и отображает любые изменения при изменении кода.

  3. Кеширование и многопоточность
    Parcel использует умное кеширование и сборку в несколько потоков, что значительно ускоряет процесс сборки даже в крупных проектах.

  4. Упрощённая работа с окружениями
    Parcel автоматически различает режимы разработки и продакшена без ручной настройки.

В каких проектах использовать?

Parcel будет отличным выбором, если нужно запустить проект как можно быстрее и не затрачивать сил на создание конфигурации сборки. Он подойдёт для следующих проектов:

  1. Малые и средние проектов, где нет сложных требований к сборке.

  2. Обучение, особенно если вы только начинаете и не хотите сразу погружаться в тонкости конфигов сборки.

Пример сборки

Воссоздадим сборку все для того же стека, что и в других сборщиках: Pug, SCSS, TypeScript. Сначала создадим базовую структуру проекта:

project/
├── src/
│   ├── index.pug
│   ├── main.ts
│   └── styles.scss
├── package.json
└── .parcelrc

Теперь необходимо создать конфигурационный файл сборки, в котором мы только подключим плагин для обработки .pug файлов, т.к. все остальные технологии Parcel поддерживает из коробки и установит необходимые плагины автоматически:

{
  "extends": "@parcel/config-default",
  "transformers": {
    "*.pug": ["@parcel/transformer-pug"]
  }
}

Осталось лишь добавить npm‑скрипты для запуска сборки:

"scripts": {
  "dev": "parcel src/index.pug",
  "build": "parcel build src/index.pug"
}

Итог

Увидев все сборщики в работе, можем подвести итоговую таблицу:

Характеристика

Webpack

Vite

Parcel

Скорость разработки

Средняя

Очень высокая

Высокая

Конфигурация

Гибкая, но требует времени

Простая, часто «из коробки

Почти не требуется, zero config

Поддержка плагинов

Огромное количество плагинов

Большое количество плагинов

Ограничена, но многое встроено

Подходит для

Крупных проектов

Малых/средних проектов, SPA,

Малых/средних проектов, обучения

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

При желании узнать больше о мире Фронтенд‑разработки можете посетить мою группу Вконтакте с обучающими видео и другими полезными материалами — https://vk.com/sanwed

© Habrahabr.ru