совместное использование мини-css-плагина для извлечения и загрузчика стилей

#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 использовать in dev mode amp; MiniCssExtractPlugin in prod 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 в разработке.