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
- Микрофронтенды: Позволяют создавать микрофронтенд архитектуру.
- Переиспользование кода: Позволяют использовать код из других приложений.
- Независимая разработка: Позволяют разрабатывать приложения независимо друг от друга.
- Динамическая загрузка: Позволяют загружать код во время выполнения.