Output two different CSS files using MiniCSSExtractPlugin with Webpack 4

Viewed 2173

I have SCSS files all over my ./src directory which is either editor-[...].scss or frontend-[...].scss, my goal is to setup MiniCSSExtractPlugin in a way that it takes in these scss files and based on whether it is editor- or frontend- output it into different CSS files.

Right now I have

             {
                test: /\.(css|scss)$/,
                use: [ {
                    loader: MiniCssExtractPlugin.loader
                },
                'css-loader',
                {
                    loader: 'postcss-loader',
                    options: {
                        plugins: [
                            require( 'autoprefixer' )
                        ]
                    }
                },
                {
                    loader: 'sass-loader',
                    query: {
                        outputStyle:
                            'production' === process.env.NODE_ENV ? 'compressed' : 'nested'
                    }
                } ]
            },

And then

plugins: [
        new MiniCssExtractPlugin({
            filename: './build/myawesomeapp-editor.css'
        })
]

I can't seem to figure out, how to set two outputs. I know I have to use regexp to look for files, but I don't know how to extract them to different files after I do it.

1 Answers

I know this question is a bit old now, but I have just spend a few days my self trying to work this out. Admittedly I don't know too much about webpack at this stage, so it did take longer than it should have.

What I ended up doing is what is specified here https://github.com/webpack-contrib/mini-css-extract-plugin#extracting-css-based-on-entry

How I implemented it was to create a config json file containing a list of scss files that need to be used

{
   "file1": {
      "scss": "file1",
   },
   "file2": {
      "scss": "file2",
   },
}

(there are reasons as to why my particular setup is not using an array here)

Then in my webpack.config file I have the following

const themeConfig = require('./src/config/themes.json');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const _ = require('lodash');

Then I loop over the config to create the split chunks config specific to the themes

// specify the theme split chunk config
let themeChunks = {};
let themeFiles = [];
for (let i in themeConfig) {
  const theme = themeConfig[i];
  themeChunks[_.camelCase(`theme_${i}`)] = {
    name: `theme-${theme.css}`,
    test: new RegExp(`src\/resources\/styles\/themes\/${theme.css}.scss$`),
    chunks: 'all',
    enforce: true,
  };

  themeFiles.push(`./src/resources/styles/themes/${theme.css}.scss`);
}

Note: the test line should be the path to your scss files

Then my entry looks like this

entry: {
    app: ['./src/app.js'],
    themes: themeFiles
  },

My split chunks looks like this

splitChunks: {
  hidePathInfo: true, 
  chunks: "initial",
  maxSize: 200000, 
  cacheGroups: {
    default: false,

    // add the theme config
    ...themeChunks,
  }
}

And finally my rules


{
  test: /\.scss$/,
  use: [
    { loader: MiniCssExtractPlugin.loader, },
    { loader: 'css-loader' },
    { loader: 'sass-loader' }
  ],
},

This is based on the example from dwatts3624 https://github.com/webpack-contrib/mini-css-extract-plugin/issues/45#issuecomment-425645975

I hope this helps anyone who comes across this

Related