Skip to main content

Webpack

Основные понятия

  • Разработка (development): Режим для локальной разработки, с быстрой сборкой и возможностью отладки.
  • Продакшен (production): Режим для сборки оптимизированного кода, готового к развертыванию.

webpack.dev.js (Конфигурация для разработки)

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

module.exports = {
mode: 'development', // Режим разработки
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
devtool: 'inline-source-map', // Source maps для отладки
devServer: {
static: './dist',
hot: true, // Горячая перезагрузка
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(png|svg|jpg|jpeg|gif)<span class="math-inline">/i,
type\: 'asset/resource',
\},
\{
test\: /\\\.\(woff\|woff2\|eot\|ttf\|otf\)</span>/i,
type: 'asset/resource',
},
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
},
},
},
],
},
plugins: [
new HtmlWebpackPlugin({
title: 'Development',
template: './src/index.html',
}),
],
};

webpack.prod.js (Конфигурация для продакшена)

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // Плагин для извлечения CSS в отдельные файлы
const TerserPlugin = require('terser-webpack-plugin'); // Плагин для минификации JavaScript
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); // Плагин для минификации CSS

module.exports = {
mode: 'production', // Режим продакшена
entry: './src/index.js',
output: {
filename: '[name].[contenthash].bundle.js', // Добавляем хэш к имени файла
path: path.resolve(__dirname, 'dist'),
clean: true,
},
devtool: 'source-map', // Source maps для отладки в продакшене
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader'], // Используем MiniCssExtractPlugin
},
{
test: /\.(png|svg|jpg|jpeg|gif)<span class="math-inline">/i,
type\: 'asset/resource',
\},
\{
test\: /\\\.\(woff\|woff2\|eot\|ttf\|otf\)</span>/i,
type: 'asset/resource',
},
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
},
},
},
],
},
optimization: {
minimizer: [
new TerserPlugin(), // Минификация JavaScript
new CssMinimizerPlugin(), // Минификация CSS
],
},
plugins: [
new HtmlWebpackPlugin({
title: 'Production',
template: './src/index.html',
}),
new MiniCssExtractPlugin({ // Создаем экземпляр плагина
filename: '[name].[contenthash].css', // Добавляем хэш к имени файла
}),
],
};

Отличия между webpack.dev.js и webpack.prod.js

  • Режим (mode): development для разработки, production для продакшена.
  • Source maps (devtool): inline-source-map для разработки (быстрее), source-map для продакшена (лучше для отладки).
  • Минификация: В webpack.prod.js используются TerserPlugin и CssMinimizerPlugin для минификации JavaScript и CSS.
  • Хеширование имен файлов: В webpack.prod.js к именам файлов добавляются хеши ([contenthash]) для кэширования в браузере.
  • Извлечение CSS: В webpack.prod.js используется MiniCssExtractPlugin для извлечения CSS в отдельные файлы.
  • Оптимизация: В webpack.prod.js используется блок optimization для настройки оптимизации сборки.

Запуск сборки

  • Разработка: npx webpack --config webpack.dev.js
  • Продакшен: npx webpack --config webpack.prod.js

Module Federation

Основные понятия

  • Module Federation: Плагин Webpack, позволяющий динамически загружать код из других приложений во время выполнения.
  • Host: Приложение, которое потребляет удаленные модули.
  • Remote: Приложение, которое предоставляет удаленные модули.
  • Shared Modules: Модули, которые могут быть использованы совместно между Host и Remote приложениями.

Пример конфигурации (webpack.config.js)

Host приложение

const { ModuleFederationPlugin } = require("webpack").container;
const path = require("path");

module.exports = {
// ... другие настройки
plugins: [
new ModuleFederationPlugin({
name: "host", // Имя Host приложения
remotes: {
remoteApp: "remote@http://localhost:3001/remoteEntry.js", // Подключаем Remote приложение
},
shared: {
react: { singleton: true, requiredVersion: "^17.0.0" }, // Общие модули
"react-dom": { singleton: true, requiredVersion: "^17.0.0" },
},
}),
],
devServer: {
port: 3000,
},
};

Remote приложение

const { ModuleFederationPlugin } = require("webpack").container;
const path = require("path");

module.exports = {
// ... другие настройки
plugins: [
new ModuleFederationPlugin({
name: "remote", // Имя Remote приложения
filename: "remoteEntry.js", // Имя файла для удаленных модулей
exposes: {
"./Button": "./src/Button", // Экспортируем модуль Button
},
shared: {
react: { singleton: true, requiredVersion: "^17.0.0" }, // Общие модули
"react-dom": { singleton: true, requiredVersion: "^17.0.0" },
},
}),
],
devServer: {
port: 3001,
},
};

Использование удаленного модуля в Host приложении

import React, { lazy, Suspense } from "react";

const RemoteButton = lazy(() => import("remoteApp/Button")); // Импортируем удаленный модуль

const App = () => (
<div>
<h1>Host Application</h1>
<Suspense fallback="Loading...">
<RemoteButton />
</Suspense>
</div>
);

export default App;

Преимущества Module Federation

  • Микрофронтенды: Позволяют создавать микрофронтенд архитектуру.
  • Переиспользование кода: Позволяют использовать код из других приложений.
  • Независимая разработка: Позволяют разрабатывать приложения независимо друг от друга.
  • Динамическая загрузка: Позволяют загружать код во время выполнения.