9. Обработка CSS
Обработка CSS в Webpack — это целая экосистема инструментов. Правильная настройка CSS pipeline критически важна для производительности, изоляции стилей и удобства разработки. Рассмотрим все уровни: от базового импорта CSS до CSS Modules и PostCSS.
Базовая цепочка: style-loader + css-loader
Заголовок раздела «Базовая цепочка: style-loader + css-loader»npm install --save-dev css-loader style-loadermodule: { rules: [{ test: /\\.css$/, use: ['style-loader', 'css-loader'], // Порядок справа налево: // 1. css-loader — разрешает @import, url(), создаёт JS модуль // 2. style-loader — инжектирует CSS в <style> тег }]}// В коде:import './App.css'; // CSS инжектируется в DOM при импортеКогда использовать style-loader: только в development. В production используйте MiniCssExtractPlugin.
MiniCssExtractPlugin — CSS в отдельные файлы
Заголовок раздела «MiniCssExtractPlugin — CSS в отдельные файлы»npm install --save-dev mini-css-extract-pluginconst MiniCssExtractPlugin = require('mini-css-extract-plugin');const isDev = process.env.NODE_ENV === 'development';
module.exports = { module: { rules: [{ test: /\\.css$/, use: [ isDev ? 'style-loader' : MiniCssExtractPlugin.loader, 'css-loader', ], }], }, plugins: [ !isDev && new MiniCssExtractPlugin({ filename: '[name].[contenthash:8].css', }), ].filter(Boolean),};CSS Modules — изоляция стилей
Заголовок раздела «CSS Modules — изоляция стилей»CSS Modules автоматически генерируют уникальные имена классов, предотвращая коллизии:
{ test: /\\.module\\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { modules: { localIdentName: '[name]__[local]--[hash:base64:5]', }, }, }, ],}// Button.module.css.button { background: blue; }.primary { color: white; }
// Button.tsximport styles from './Button.module.css';// styles.button → 'Button__button--abc12'// styles.primary → 'Button__primary--def34'
function Button() { return <button className={styles.button}>Click</button>; // В HTML: <button class="Button__button--abc12">Click</button>}SASS/SCSS
Заголовок раздела «SASS/SCSS»npm install --save-dev sass-loader sass{ test: /\\.s[ac]ss$/i, use: [ isDev ? 'style-loader' : MiniCssExtractPlugin.loader, { loader: 'css-loader', options: { importLoaders: 2 }, // Количество лоадеров после css-loader }, 'sass-loader', ],}PostCSS — трансформация CSS
Заголовок раздела «PostCSS — трансформация CSS»PostCSS — это инструмент для трансформации CSS с помощью плагинов (Autoprefixer, CSS Nesting, etc.):
npm install --save-dev postcss-loader postcss autoprefixer postcss-preset-env{ test: /\\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { importLoaders: 1 } }, { loader: 'postcss-loader', options: { postcssOptions: { plugins: [ 'autoprefixer', // Вендорные префиксы ['postcss-preset-env', { // Современный CSS → совместимый stage: 3, features: { 'nesting-rules': true, }, }], ], }, }, }, ],}Или через postcss.config.js:
module.exports = { plugins: [ require('autoprefixer'), require('postcss-preset-env')({ stage: 3 }), ],};Полный production конфиг CSS
Заголовок раздела «Полный production конфиг CSS»const isDev = process.env.NODE_ENV === 'development';
const getCssLoaders = (cssModules = false) => [ isDev ? 'style-loader' : MiniCssExtractPlugin.loader, { loader: 'css-loader', options: { modules: cssModules ? { localIdentName: '[name]__[local]--[hash:base64:5]' } : false, importLoaders: 2, sourceMap: isDev, }, }, { loader: 'postcss-loader', options: { postcssOptions: { plugins: ['autoprefixer'] } } }, 'sass-loader',];
module: { rules: [ { test: /\\.module\\.(css|scss)$/, use: getCssLoaders(true) }, { test: /(?<!module)\\.(css|scss)$/, use: getCssLoaders(false) }, ],}Ниже — интерактивный визуализатор CSS pipeline. Выберите конфигурацию и посмотрите как CSS проходит через каждый инструмент.