javascript42
Главная
Все учебники
Блог
Учебник Webpack
Введение в сборку модулей
Что такое сборщик модулей и зачем он нужен
Эволюция инструментов сборки: от Grunt и Gulp к Webpack
Место Webpack в современном фронтенд-стеке
Сравнение с Vite, Rollup, Parcel, esbuild
Когда Webpack оправдан, а когда избыточен
Установка и первые шаги
Требования к окружению: Node.js и npm/yarn/pnpm
Локальная и глобальная установка Webpack
webpack и webpack-cli: разница и взаимодействие
Структура выходного бандла: что генерирует Webpack по умолчанию
Концепции ядра
Точки входа (entry)
Выходные файлы (output)
Загрузчики (loaders)
Плагины (plugins)
Режимы сборки (mode)
Граф зависимостей: как Webpack обходит модули
Чанки (chunks) и их роль в сборке
Рантайм Webpack: bootstrap-код и его назначение
Конфигурационный файл
Формат и расположение webpack.config.js
Экспорт объекта, функции и Promise
Конфигурация через переменные окружения
Слияние конфигураций с webpack-merge
Несколько конфигурационных файлов в одном проекте
Типизация конфигурации через JSDoc и TypeScript
Режимы development и production: ключевые отличия
Режим none и когда он используется
Точки входа и граф модулей
Одиночная точка входа
Множественные точки входа
Динамические имена точек входа
Зависимости, общие между несколькими точками входа
dependOn и оптимизация общих чанков между entry
Порядок обработки точек входа
Выходные файлы и именование
Параметр path и publicPath
Шаблоны имён файлов: [name], [hash], [contenthash], [chunkhash]
Различия между типами хешей и стратегии кэширования
clean: автоматическая очистка директории вывода
Настройка library для публикации как npm-пакета
Управление именами чанков через магические комментарии
assetModuleFilename и именование ресурсов
Загрузчики
Принцип работы загрузчиков: трансформация исходников
Синтаксис подключения: inline, через config, через CLI
Порядок применения загрузчиков: справа налево, снизу вверх
Передача опций загрузчику
Условное применение загрузчиков: include, exclude, resource
Написание собственного загрузчика
Синхронные и асинхронные загрузчики
Загрузчик с несколькими возвращаемыми значениями (pitch)
Контекст загрузчика: this и доступные утилиты
Работа с JavaScript
Обработка CommonJS, ESM и UMD модулей
Babel-loader: настройка транспиляции
Пресеты и плагины Babel в связке с Webpack
Browserslist и целевые браузеры
esbuild-loader как альтернатива babel-loader
swc-loader: возможности и ограничения
Обработка синтаксиса top-level await
Полифилы: автоматические и ручные подходы
Shim-модули и ProvidePlugin
Работа с TypeScript
ts-loader: базовая настройка
babel-loader + @babel/preset-typescript: преимущества и ограничения
transpileOnly и отдельный запуск tsc для проверки типов
fork-ts-checker-webpack-plugin: параллельная проверка типов
Разрешение путей: tsconfig paths и tsconfig-paths-webpack-plugin
Декларации типов для ресурсов (svg, css, images)
Работа со стилями
css-loader: импорт CSS в JavaScript
style-loader: встраивание стилей в DOM
MiniCssExtractPlugin: вынос CSS в отдельные файлы
Порядок загрузчиков: css-loader → style-loader vs MiniCssExtractPlugin
Препроцессоры: sass-loader, less-loader, stylus-loader
PostCSS и postcss-loader
Autoprefixer и preset-env для CSS
CSS Modules: изоляция стилей
Глобальные и локальные стили при использовании CSS Modules
Обработка @import и url() внутри CSS
Минификация CSS: CssMinimizerWebpackPlugin
Работа с ресурсами (Asset Modules)
Asset Modules в Webpack 5: замена file-loader и url-loader
Тип resource: вынос файла на диск
Тип inline: встраивание в Base64
Тип source: обработка текстовых ресурсов
Тип asset: автоматический выбор стратегии по размеру
Настройка порога для inline через parser.dataUrlCondition
Обработка SVG: как ресурс, как компонент, как спрайт
Шрифты: подключение и оптимизация
Изображения: форматы webp, avif и автоконвертация
Генерация иконок и favicons
Разрешение модулей (Resolve)
Алгоритм разрешения: node_modules и относительные пути
Расширения файлов: extensions
Алиасы: alias и их использование в крупных проектах
modules: нестандартные директории для поиска
mainFields и mainFiles: точки входа пакетов
Разрешение симлинков: symlinks
Работа с монорепозиториями и workspace
Кастомные резолверы
Плагины резолвера: tsconfig-paths, babel-plugin-module-resolver
Разделение кода (Code Splitting)
Зачем разделять код: производительность и кэширование
Несколько точек входа как инструмент разделения
SplitChunksPlugin: автоматическое выделение общих зависимостей
Конфигурация chunks: initial, async, all
Группы кэширования (cacheGroups): настройка стратегий
Вынос vendor-кода в отдельный чанк
Минимальный размер и количество использований чанка
Динамический импорт: import()
Магические комментарии: webpackChunkName, webpackPrefetch, webpackPreload
Prefetch и preload: браузерные подсказки загрузки
Ручное управление чанками через Entry и dependOn
Ленивая загрузка
Паттерн ленивой загрузки компонентов
Ленивая загрузка маршрутов в React, Vue, Angular
Условная загрузка по событию пользователя
Гранулярность разделения: слишком мало vs слишком много чанков
Анализ влияния ленивой загрузки на TTI и LCP
Дерево зависимостей и Tree Shaking
Принцип Tree Shaking: статический анализ ESM
Условия для работы Tree Shaking: sideEffects и ESM
Поле sideEffects в package.json
Пометка конкретных файлов как имеющих побочные эффекты
usedExports и минимизатор: взаимозависимость
Inner Graph Analysis в Webpack 5
Проблемы с CommonJS и Tree Shaking
Библиотеки с плохой поддержкой Tree Shaking: обходные решения
Проверка результата: анализ бандла
Оптимизация бандла
Режим production и встроенные оптимизации
TerserPlugin: минификация JavaScript
Настройки Terser: mangle, compress, comments
Замена TerserPlugin на esbuild-minimize-plugin или SWC
CssMinimizerPlugin: минификация стилей
optimization.minimize и optimization.minimizer
optimization.concatenateModules: Scope Hoisting
Анализ бандла: webpack-bundle-analyzer, statoscope
Дедупликация модулей
ModuleConcatenationPlugin и его ограничения
Интерпретация stats.json
Кэширование сборок
Файловая система кэширования в Webpack 5: filesystem cache
Память как тип кэша: memory cache
Настройка cacheDirectory и cacheLocation
Инвалидация кэша: version, buildDependencies, name
Кэш в CI/CD: что сохранять, что нет
Постоянное кэширование и contenthash
Кэш резолвера и кэш загрузчиков
Hard Source и другие устаревшие подходы
Сервер разработки
webpack-dev-server: установка и базовая настройка
devServer.static: раздача статики
Hot Module Replacement (HMR): принцип работы
Настройка HMR для CSS, JavaScript, React, Vue
devServer.proxy: проксирование API-запросов
https и самоподписанные сертификаты
historyApiFallback для SPA
Настройка headers, compress, port, host
webpack-dev-middleware для интеграции с Express/Koa
Разница между watch mode и dev server
Hot Module Replacement в деталях
Протокол HMR: события и сообщения
module.hot API: accept, decline, dispose
Boundaries HMR: границы обновления модулей
Ошибки при HMR и полная перезагрузка страницы
react-refresh-webpack-plugin
vue-loader и встроенная поддержка HMR
Написание HMR-обработчика вручную
Source Maps
Зачем нужны Source Maps
Типы Source Maps: eval, inline, cheap, module, hidden, nosources
Рекомендуемые значения для development и production
Source Maps для CSS
Source Maps и безопасность: скрытие исходников от пользователей
hidden-source-map и загрузка карт в Sentry/Bugsnag
devtool vs SourceMapDevToolPlugin
Проверка корректности Source Maps в браузере
Плагины
Архитектура плагинов: хуки компилятора и компиляции
Tapable: типы хуков (SyncHook, AsyncHook, Waterfall, Bail)
Жизненный цикл компиляции: основные хуки
HtmlWebpackPlugin: генерация HTML
Шаблоны HTML и переменные окружения в шаблоне
CopyWebpackPlugin: копирование статических файлов
DefinePlugin: встраивание констант
EnvironmentPlugin: переменные окружения
BannerPlugin: добавление комментариев в файлы
IgnorePlugin: исключение модулей
NormalModuleReplacementPlugin и ContextReplacementPlugin
CompressionPlugin: gzip и brotli сжатие
ImageMinimizerPlugin: оптимизация изображений
Написание собственного плагина
Отладка плагина
Работа с переменными окружения
.env файлы и dotenv-webpack
NODE_ENV и его влияние на сборку
Разграничение конфигов: .env.development, .env.production
DefinePlugin и process.env
Доступ к переменным в клиентском коде
Безопасность: что нельзя выносить в клиентский бандл
Множественные конфигурации и сборки
Экспорт массива конфигураций
Параллельная сборка нескольких таргетов
Сборка под разные target: web, node, electron
Универсальные (SSR) бандлы: client и server конфигурации
Сборка библиотеки и приложения одновременно
Сборка библиотек
output.library: name, type, export
Форматы: var, this, window, umd, commonjs, module, amd
Externals: исключение зависимостей из бандла
Сохранение ESM-структуры для Tree Shaking потребителями
Генерация типов при сборке библиотеки
Конфигурация package.json: main, module, exports, types
Peer dependencies и их обработка
Module Federation
Концепция микрофронтендов и место Module Federation
Host и Remote: роли приложений
Настройка ModuleFederationPlugin
exposes: публикация модулей
remotes: подключение удалённых модулей
shared: управление общими зависимостями
Singleton-зависимости и версионирование
Асинхронная загрузка federated-модулей
Динамические Remote URL
Module Federation и TypeScript: декларации типов
Отладка и обработка ошибок загрузки Remote
Module Federation 2.0: новые возможности
Webpack и фреймворки
Create React App и внутренняя конфигурация Webpack
Ejecting и ручная настройка CRA
CRACO и react-app-rewired: переопределение без eject
Next.js: кастомизация Webpack через next.config.js
Vue CLI и vue.config.js
Angular и webpack builder
Svelte и svelte-loader
Storybook и его внутренний Webpack
Производительность сборки
Измерение времени сборки: speed-measure-webpack-plugin
Сужение области обработки: include/exclude в загрузчиках
thread-loader: параллельная обработка модулей
cache-loader (устаревший) и переход на встроенный кэш
Уменьшение количества resolve: extensions и alias
Избегание тяжёлых загрузчиков в режиме разработки
Точечное отключение оптимизаций в development
Анализ узких мест с помощью stats и профилировщика
Влияние размера node_modules на сборку
Оптимизация больших монорепозиториев
Webpack 5: новое по сравнению с Webpack 4
Asset Modules вместо file-loader и url-loader
Постоянное кэширование (Persistent Caching)
Module Federation
Tree Shaking: Inner Graph
Улучшенный алгоритм генерации идентификаторов чанков
Отказ от Node.js полифилов по умолчанию
Top-level await поддержка
Улучшения в SplitChunksPlugin
Изменения в API плагинов и загрузчиков
Миграция с Webpack 4 на Webpack 5
Тестирование и Webpack
Запуск тестов без сборки: Jest и moduleNameMapper
babel-jest и ts-jest в обход Webpack
Мокирование статических ресурсов в тестах
Webpack-сборка в интеграционных тестах
Тестирование собственных загрузчиков и плагинов
memory-fs и компилятор в тестовом режиме
Webpack в Node.js-окружении
target: node и его отличия от web
Externals для Node.js: externalsPresets
Сборка CLI-инструментов и серверных приложений
Обработка нативных .node модулей
Electron: main и renderer процессы
SSR: серверный и клиентский бандлы
Продвинутая работа с конфигурацией
Программный API: webpack() и compiler
Запуск Webpack из скрипта Node.js
Получение stats и обработка ошибок программно
watching: запуск наблюдателя программно
Компилятор и MultiCompiler
Интеграция с gulp через программный API
Кастомные файловые системы: inputFileSystem, outputFileSystem
Отладка и диагностика
Уровни логирования: infrastructureLogging
stats: управление детализацией вывода
Профилирование с --profile и node --inspect
Поиск дублирующихся модулей
Circular dependencies и circular-dependency-plugin
Анализ размера модулей
Диагностика медленных загрузчиков
Отладка резолва: enhanced-resolve и его логи
Безопасность сборки
Subresource Integrity: SriPlugin
Ограничение размера бандла: performance hints
Аудит зависимостей и цепочка поставок
Исключение чувствительных данных из бандла
Content Security Policy и nonce в HtmlWebpackPlugin