4

When i try to add the sass-loader and run webpack there is multiple chunck .css files in the dist folder instead of just the bundled one named "style.css".

My dist output folder looks like:

0.e749007119be51de03e4.js  1.e749007119be51de03e4.js  bundle.e749007119be51de03e4.js
0.style.css                1.style.css

I guess it's because of the Mini-css-extract-plugin but i can't figure out how to fix it.

Here is my webpack file:

const webpack = require('webpack');
const { resolve } = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

const ROOT = resolve(__dirname);
const SRC = resolve(ROOT, 'src');

module.exports = {
  mode: 'development',
  devtool: 'cheap-module-eval-source-map',
  entry: {
    bundle: [
      'react-hot-loader/patch',
      'webpack-hot-middleware/client?reload=true',
      resolve(SRC, 'client', 'index.js'),
    ]
  },
  output: {
    path: resolve(ROOT, 'dist', 'client'),
    filename: '[name].[hash].js',
    publicPath: '/'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: 'babel-loader',
        exclude: /node_modules/
      },
      {
        test: /\.css$/,
        include: resolve(__dirname, 'node_modules', 'react-toolbox'),
        use: [
          MiniCssExtractPlugin.loader,
          // 'style-loader',
          {
            loader: 'css-loader',
            options: {
              modules: true,
              sourceMap: true,
              importLoaders: 1,
              localIdentName: '[name]_[local]_[hash:base64:5]'
            }
          },
          // 'postcss-loader'
        ]
      },
      {
        test: /\.scss$/,
        use: ['style-loader', MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
      },
      {
        test: /\.css$/,
        exclude: resolve(__dirname, 'node_modules', 'react-toolbox'),
        use: ['style-loader', 'css-loader']
      },
      {
        test: /\.(jpe?g|svg|png|gif)$/,
        use: ['file-loader']
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/,
        use: ['file-loader']
      }
    ]
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new MiniCssExtractPlugin({
      filename: 'style.css',
    }),
  ]
};

Any idea ?

11
  • That is code splitting, why you are bothered by that? It is helping you... big file size harms the user Commented Aug 16, 2018 at 13:04
  • There is two problems coming with this way. If i wanna use a plugin like html-webpack-plugin the index.html file is not filled with the <link href="/bundle.css" rel="stylesheet"> anymore. Secondly the normal behavior of MiniCssExtractPlugin shouldn't be to create a file style.css like i precised in the constructor ? Commented Aug 16, 2018 at 13:24
  • No, since you have async chunks, it is going to create a style.css for each style that is removed from those async chunks. Commented Aug 16, 2018 at 13:25
  • 1
    I assure you that if you are using html-webpack-plugin it is going to work. It is just not added there because those css had not came from one of the entry points. THat is why it is not inserted directly into the html. I have a similar project and it works perfectly. Commented Aug 16, 2018 at 13:26
  • 1
    i'll post this as an answer, on all those questions you made Commented Aug 16, 2018 at 13:50

2 Answers 2

2

There is two problems coming with this way. If i wanna use a plugin like html-webpack-plugin the index.html file is not filled with the anymore. Secondly the normal behavior of MiniCssExtractPlugin shouldn't be to create a file style.css like i precised in the constructor ?

No, since you have async chunks, it is going to create a style.css for each style that is removed from those async chunks.

I assure you that if you are using html-webpack-plugin it is going to work. It is just not added there because those css had not came from one of the entry points. THat is why it is not inserted directly into the html. I have a similar project and it works perfectly.

If those are not emmited from the entry point, there are going to be loaded dynamically by webpack once those chunks are requested.

Big files harms users. Code splitting is always the answer for everything!!

Sign up to request clarification or add additional context in comments.

1 Comment

Seems to be the right answer, i marked it as the solution meanwhile i test everything !
1

Check out this piece of code from the documentation

module: {
  rules: [
    {
      test: /\.(sa|sc|c)ss$/,
      use: [
        devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
        'css-loader',
        'postcss-loader',
        'sass-loader',
      ],
    }
  ]
}

if you see carefully you'll see that it's using style-loader in dev mode and MiniCssExtractPlugin.loader for production. So in production it will generate another file for css.

What you need to do is this:

In your package.json file in the script section you need to pass a env variable devMode like this

"scripts": {
  "webpack": "webpack",
  "start": "npm run webpack -- --env.mode=development"
}

Then in your webpack.config.js file you need to do this

module.exports = (env) => {
  const devMode = env.mode === 'development'
  return {
    mode: env.mode, // will be development
    devtool: ...,
    entry: { ... },
    output: { ... },
    module: {
      rules: [
        {
          test: /\.scss$/,
          use: [devMode ? 'style-loader' : MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
        }          
      ]
    }
  }
}

That should be ok, hope it helps.

3 Comments

Firstly thanks for your quick answer ! I have seen this before too in the documentation, the problem is that even do i'm trying this way with style-loader in development mode the scss files aren't outputed in any .css file anymore..
did you try merging your rules for css maybe that's the problem, right now you have a couple of them
I cannot merge them because i'm using specific configuration with include/excluse for the react-toolbox library.. Gonna still try :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.