using mini-css-extract-plugin and style-loader together

spetsnaz picture spetsnaz · Apr 14, 2019 · Viewed 10.3k times · Source

I am new to that webpack thing and following some tutorials to learn basics.

I would like to use style-loader to inject stylesheets during development (with HMR enabled) and want to use MiniCssExtractPlugin for production builds. But when I use MiniCssExtractPlugin plugin, I loose injecting feature of style-loader.

Please see my webpack config :

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
    }
};

Answer

Krystian picture Krystian · Nov 4, 2019

The second parameter of the function assigned in webpack.config.js to module.exports contains the mode flag (--mode [development|production]). So here you can use the mode to load MiniCssExtractPlugin.loader or style-loader.

While developing, using style-loader is faster than extracting the styles each time. But in production, you should extract the styles in separate files to avoid the loading glitch in your web, when the styles load after the HTML, and you see your page without styles for a moment.

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'
        ],
      },
    ],
  },
});