question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Support multiple instances of MiniCssExtractPlugin to generate multiple CSS theme output from the single CSS input

See original GitHub issue
  • Operating System: Mac OS 10.14.5
  • Node Version: v8
  • NPM Version: v5
  • webpack Version: v4
  • mini-css-extract-plugin Version: v0.8.0

Feature Proposal

Support multiple instances of MiniCssExtractPlugin to generate multiple themed CSS outputs from the shared singular CSS/SCSS input.

Sample code
const __home = path.resolve(__dirname, '');

module.exports = {
    entry: path.resolve('src/index.js'),
    output: {
        filename: "[name].js",
        path: path.resolve("dist")
    },
    module: {
        rules: [
            {
                test: /\.scss$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    "css-loader",
                    {
                        loader: "sass-loader",
                        options: {  includePaths: [path.resolve(__home, "src/light-theme"),]}

                    }
                ]
                // Want to do something like this to generate a second CSS theme bundle based on the shared CSS input extracted from the JS
                // use: [
                //     MiniCssExtractPlugin.loader,
                //     "css-loader",
                //     {
                //         loader: "sass-loader",
                //         options: {  includePaths: [path.resolve(__home, "src/dark-theme"),]}
                //
                //     }
                // ]
            }
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: "light-theme.css"
        })
        // new MiniCssExtractPlugin({
        //     filename: "dark-theme.css"
        // })
    ]
};

Feature Use Case

The use-case for this is an app that wants to support both a dark and light mode styles without having to rely on CSS-in-JS solutions. Instead, it would be nice to extract the CSS from the common singular source CSS and output that into 2 separate stylesheets which use different SCSS variables to generate the dark and light variants of the stylesheet.

This seems feasible if multiple instances of MiniCssExtractPlugin were supported:

One that applies the light-mode theme variables via the configured sass-loader in the first mini-css-extract configuration.

And a second instance that applies the dark-mode theme variables via the configured sass-loader in the second mini-css-extract configuration.

If there is another way to achieve this, I’d be very interested.

Link to test repo

https://github.com/bjankord/webpack4-multi-theme

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:17
  • Comments:23 (11 by maintainers)

github_iconTop GitHub Comments

7reactions
mmarekbbcommented, Jun 17, 2021

As mentioned above, using splitChunks is not the solution. ExtractTextPlugin supported multiple instances, which let us in combination with the multi-loader to pass all styles that all match the same test rule (basically just ending with .scss) to pass through two instances of it - say a light and dark theme. The dark theme then had some scss variables prepended before compilation.

  1. I don’t think this can be achieved with splitChunks. splitChunks decides which file goes to which bundle, but we need all files to go to two bundles instead.
  2. Creating multiple entry points is not great, because we would need to import all individual scss files in light.scss and dark.scss before adding them to the entries, at which point we can just run the sass compiler manually without webpack.

The proposed solution would be for the MiniCssExtractPlugin to expose a loader that’s specific to its instance. A sample config would be something like this -

import multiLoader from 'multi-loader';
import combineLoaders from 'webpack-combine-loaders';

const extractLightTheme = new MiniCssExtractPlugin({ filename: 'light.css' });
const extractDarkTheme = new MiniCssExtractPlugin({ filename: 'dark.css' });

{
  test: /\.scss$/, // thanks to multiLoader this goes through both extract plugins
  use: multiLoader(
    combineLoaders([
      extractLightTheme.loader,
      'css-loader',
      { loader: 'sass-loader', options: { additionalData: '@import "light-theme-vars.scss"' } }
    ]),
    combineLoaders([
      extractDarkTheme.loader,
      'css-loader',
      { loader: 'sass-loader', options: { additionalData: '@import "dark-theme-vars.scss"' } }
    ]),
  )
}

@alexander-akait I don’t think this is possible to achieve with the current version of MiniCssExtractPlugin, because it only exposes a single global loader. We consider opening a pull request for adding this functionality if it’s wanted here.

2reactions
benquarmbycommented, Mar 31, 2021

Splitting chunks is for dividing bundles (aka code splitting). Generating themes is about multiplying bundles. I’m convinced that theming is an entirely different problem than what splitChunks is designed to solve.

After going deep down this rabbit hole, the escape hatch was to stay on weback v4 and use the experimental and totally unsupported extract-css-loader@4.0.0-beta.0. The fact that it supports multiple instances (again, this is a multiplication, not division problem) works exactly as expected.

Read more comments on GitHub >

github_iconTop Results From Across the Web

MiniCssExtractPlugin - webpack
This plugin extracts CSS into separate files. It creates a CSS file per JS file which contains CSS. It supports On-Demand-Loading of CSS...
Read more >
Output 2 (or more) .css files with mini-css-extract-plugin in ...
And as a result, I got 2 css files in output. How can I reach the same with mini-css-extract-plugin ? As according to...
Read more >
mini-css-extract-plugin - npm
extracts CSS into separate files. Latest version: 2.7.2, last published: 23 days ago. Start using mini-css-extract-plugin in your project by ...
Read more >
How to configure CSS and CSS modules in webpack
One of the first thing you need to configure in your webpack project is CSS ... You need two loaders to support CSS...
Read more >
Separating CSS | webpack surviveJS - GitHub Pages
Webpack provides a means to generate a separate CSS bundles using mini-css-extract-plugin (MCEP). It can aggregate multiple CSS files into one.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found