Mini-css-extract-plugin: Support multiple instances of MiniCssExtractPlugin to generate multiple CSS theme output from the single CSS input

Created on 16 Jul 2019  路  19Comments  路  Source: webpack-contrib/mini-css-extract-plugin

  • 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

All 19 comments

Just for information, theming in sass/scss is very painful https://www.sitepoint.com/sass-theming-neverending-story/

Problem is not in supporting multiple instance, problem what you need additional compilation for node-sass/sass, i will search solution for this

I think it is impossible without specific loaders, using your architecture. You also can't solve this using multiple ExtractTextWebpackPlugin. What is problem - problem what you have only one import sass styles, so you don't have needed modules, even we support multiple instances it is still not solve your problem

Hi, I have the same kind of need: generate multiple CSS files from one SCSS entry by passing a variable to the sass-loader.

To understand how much I am screwed, from what you say @evilebottnawi the problem is the sass import? When I ran a (very simple) multiple entries case:

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

I found that both modules are executed. This won't work for multiple sass-loader?

I think we can use multiple imports/entrypoints to achieve this, I will update docs in near future, but you can try it, should work

Very interested to know what you have in mind @evilebottnawi. I've been into the bowels of webpack recently trying to solve the exact same theme issue, and I'm not sure what you're thinking in terms of entries. Can you expand a little please?

Sorry for delay, I will provide example in near future

Hi @alexander-akait Do you have any updates here

No, why you need this? What is the problem?

Thanks for your reply @alexander-akait. It is same as @bjankord . We set theme variables by sass-loader includePaths. I want to generate different theme style files with different theme includePaths config.

https://github.com/bjankord/webpack4-multi-theme/blob/main/webpack-config.js#L22

Yep, still missing in docs, I think splitChunks should help in this...

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 [email protected]. The fact that it supports multiple instances (again, this is a multiplication, not division problem) works exactly as expected.

To help simplify the ask for this feature, here is what I'm looking to achieve:

Input:
main.js that imports main.scss (includes variables for theming)

Webpack Config to provide theming files that contain variable definitions:

[
  {
    name: 'light',
    file: 'lightTheme.scss'
  },
  {
    name: 'dark',
    file: 'darkTheme.scss'
  }
]

Expected Output:

  • A CSS file based on main.scss that uses the variables defined in lightTheme.scss

    • example: main-light.css

  • Another CSS file based on main.scss that uses the variables defined in darkTheme.scss

    • example: main-dark.css

@alexander-akait if this is possible with current features of webpack / webpack plugins, I'd look forward to seeing a demo.

Do you want split chunks?

I'm unsure how split chunks could be used to solve the feature request but would be open to a demo if split chunks can be used for this functionality.

I mean keep light and dark theme separately?

@alexander-akait This repo is a good example of what I'm hoping to achieve: https://github.com/bjankord/webpack4-multi-theme/blob/main/webpack-config.js#L26-L35

Just create dark.sass and put dark variables/imports there

I inject the light theme here: https://github.com/bjankord/webpack4-multi-theme/blob/main/webpack-config.js#L22
I'd like to have the ability to do another extraction of the CSS and in that, add the dark theme I have here: https://github.com/bjankord/webpack4-multi-theme/blob/main/src/dark-theme/_theme-vars.scss

@alexander-akait Are you on the webpack gitter? https://gitter.im/webpack/webpack
I'm wondering if there is a way we can speed up the feedback loop of this discussion?

Was this page helpful?
0 / 5 - 0 ratings