#webpack #mini-css-extract-plugin
#webpack #мини-css-плагин для извлечения
Вопрос:
Я новичок в этом веб-пакете и следую некоторым руководствам, чтобы изучить основы.
Я хотел бы использовать style-loader
для внедрения таблиц стилей во время разработки (с включенным HMR) и хочу использовать MiniCssExtractPlugin
для производственных сборок. Но когда я использую плагин MiniCssExtractPlugin, я теряю функцию ввода загрузчика стилей.
Пожалуйста, посмотрите мою конфигурацию webpack :
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const path = require('path');
module.exports = {
entry: ['./src/index.js'],
output: {
filename: 'app.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /.(sass|scss)$/,
use: [
"style-loader",
{
loader: MiniCssExtractPlugin.loader,
options: {
hmr: process.env.NODE_ENV === 'development'
}
},
"css-loader",
"sass-loader"
]
}
]
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css'
})
],
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
hot: true,
port: 3000
}
};
Комментарии:
1. «Но когда я использую плагин MiniCssExtractPlugin, я теряю возможность добавления загрузчика стилей» — что вы имеете в виду? в предыдущем предложении вы упомянули, что хотите
style-loader
использовать indev mode
amp;MiniCssExtractPlugin
inprod mode
. Ваше требование неясно. Пожалуйста, уточните
Ответ №1:
Второй параметр функции, назначенной в webpack.config.js
to module.exports
, содержит флаг mode ( --mode [development|production]
) . Итак, здесь вы можете использовать режим для загрузки MiniCssExtractPlugin.loader
или style-loader
.
При разработке использование style-loader
происходит быстрее, чем извлечение стилей каждый раз. Но в рабочей среде вы должны извлекать стили в отдельные файлы, чтобы избежать сбоя при загрузке в вашем веб-сайте, когда стили загружаются после HTML, и вы на мгновение видите свою страницу без стилей.
module.exports = (_, { mode }) => ({
// other options here
module: {
rules: [
// other rules here
{
test: /.s?css$/i,
use: [
mode === 'production'
? MiniCssExtractPlugin.loader
: 'style-loader',
'css-loader',
'sass-loader'
],
},
],
},
});
Комментарии:
1. Пожалуйста, добавьте некоторые пояснения о том, что делает код в вашем ответе и почему он должен решить проблему
Ответ №2:
если вы хотите использовать определенный загрузчик для одной среды разработки, а другой — для производства, я предлагаю вам webpack-merge , что позволит вам написать два отдельных файла конфигурации webpack на основе env.mode varriable вот пример :
это мой основной конфигурационный файл webpack :
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const webpackMerge = require("webpack-merge");
const path = require("path");
const modeConfig = env => require(`./build-utils/webpack.${env}`)(env);
module.exports = ({ mode } = { mode: "production" }) =>
webpackMerge(
{
mode,
entry: ['./src/index.js'],
output: {
filename: 'app.js',
path: path.resolve(__dirname, "dist")
},
module: {
rules: [
{
test: /.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css'
})
]
},
modeConfig(mode)
);
Как вы можете видеть в строке 6, я объявил переменную modeConfig, которая представляет собой функцию, которая возвращает значение require на основе переменной env, передаваемой через команду cli.
А теперь создайте свой webpack.production.js в папке build-utils эта папка будет содержать только конфигурацию для производственного evn :
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = () => ({
module: {
rules: [
{
test: /.(sass|scss)$/,
use: [
"style-loader",
"css-loader",
"sass-loader"
]
}
]
}
});
Далее ваш файл конфигурации разработчика
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = () => ({
module: {
rules: [
{
test: /.(sass|scss)$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
hmr: true // since u know this is dev env
}
},
"css-loader",
"sass-loader"
]
}
]
},
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
hot: true,
port: 3000
}
});
Теперь все, что вам нужно, это выполнить команду
webpack --env.mode=production
или
webpack --env.mode=development
Комментарии:
1. Чтобы минимизировать CSS 3 и файлы Javascript в рабочей среде, мне нужно было импортировать
const TerserPlugin = require("terser-webpack-plugin");
и включить егоoptimization: { minimizer: [new OptimizeCssAssetsPlugin(), new TerserPlugin()], },
, в противном случае были уменьшены только файлы CSS 3
Ответ №3:
MiniCssExtractPlugin говорит, что на самом деле вы не можете этого сделать:
Этот плагин следует использовать только в производственных сборках без загрузчика стилей в цепочке загрузчиков, особенно если вы хотите иметь HMR в разработке.