Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Webpack: mini-css-extract-plugin not outputting css file

I think I followed the documentation correctly, but it does not work at all.

What I want is to generate a css file, and do not load it in style tags with js.

In my src directory:: "scss/custom.scss" and "style.scss", and none of them is generated in output.

EDIT: src code: https://github.com/marcosroot/webpackexample

My settings are:

const path = require('path');
const BundleTracker = require('webpack-bundle-tracker');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const devMode = true;

module.exports = {
    entry: [
        './src/toggle_menu.js',
        './src/calls_apis.js'
    ],
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: devMode ? 'main.js' : 'main.[hash].js',
    },
    plugins: [
        new BundleTracker({
            filename: './webpack-stats.json'
        }),
        new MiniCssExtractPlugin({
            filename: devMode ? '[name].css' : '[name].[hash].css'
        })
    ],
    module: {
        rules: [{
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                }
            },
            {
                test: /\.scss$/,
                include: path.resolve(__dirname, 'scss/custom.scss'),
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'postcss-loader',
                    'sass-loader',
                ]
            }
        ]
    },
}
like image 211
marcos souza Avatar asked Apr 03 '19 23:04

marcos souza


2 Answers

This question is relatively old but I ran into the same problem and I wanted to share my solution. This is probably very dependent on your configuration, but anyway, my mini-css-extract-plugin did not work because:

  • I ran it with webpack -p (which an alias for production mode + minify)
  • The css rule I had setup did not clarify that it made side effects.

As a result, when I ran the build in production mode (i.e. webpack -p), it did not produce an output because when webpack saw this…

import './my-css-file.css';

…and was like "that doesn't do anything, i'll remove it from your build".


So in order to tell webpack that this type of file matters, you have to mark the rule as sideEffects: true

// ...
module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader'],
        include: [/* fill this in */],
        exclude: /node_modules/,
        // πŸ‘‡πŸ‘‡πŸ‘‡
        sideEffects: true, // πŸ‘ˆ ADD THIS
        // πŸ‘†πŸ‘†πŸ‘†
      },
    ],
  },
  // ...
}
like image 177
Rico Kahler Avatar answered Sep 27 '22 20:09

Rico Kahler


I think your trouble is coming from a wrong path resolution in your configuration :

include: path.resolve(__dirname, 'scss/custom.scss'),

It means to webpack to include only a resource located under {root}/scss/custom.scss and, given your explanation, I presume the right path should be {root}/src/scss/custom.scss.

So to include your two files {root}/src/scss/custom.scss and {root}/src/styles.scss and any other scss files under src folder, you can use :

module: {
    rules: [{
            test: /\.js$/,
            exclude: /node_modules/,
            use: {
                loader: 'babel-loader',
            }
        },
        {
            test: /\.scss$/,
            include: /src/, // <-- Change here ---------------------
            use: [
                MiniCssExtractPlugin.loader,
                'css-loader',
                'postcss-loader',
                'sass-loader',
            ]
        }
    ]
},

You can also simply remove include option if you're pretty sure there's no other roaming scss files in your project or node modules that may be found and should not be bundled at the same time (that's probably the case).

You can also supply an array of the two files by adding src in the path resolution :

include: [
   path.resolve(__dirname, 'src/scss/custom.scss'),
   path.resolve(__dirname, 'src/styles.scss'),
]

****** EDIT *******

Following your comment and from your repo, there's another few mistakes :

  • postcss-loader is not included as dev dependency and no configuration for it as well
  • You mistake what is the include option of a rule. It does simply mean that only resources that are matching the include test will be processed like configured in that rule. You still need to require the scss files at some point in your script.

I've forked your repo and set up a correct configuration with scss import in call_api.js (one of your entry point). Build and you will see the css file in the dist folder (I've set up a dumb cssnano config for postcss, that will be parsed harsh)

like image 44
Bertrand Avatar answered Sep 27 '22 19:09

Bertrand