Skip to content

Support multiple instances of MiniCssExtractPlugin #45

Closed
@james-s-turner

Description

@james-s-turner

The extract-webpack-text-plugin allows you to define multiple instances of the plugin. Does MiniCssExtractPlugin support the same feature? My end goal is to generate multiple bundles for SASS themes.

Activity

michael-ciniawsky

michael-ciniawsky commented on Mar 20, 2018

@michael-ciniawsky
Member

Please describe your use case and provide your config, this might not be needed anymore with mini-css-extract-plugin

james-s-turner

james-s-turner commented on Mar 20, 2018

@james-s-turner
Author

Hi @michael-ciniawsky - thanks for the prompt response. Hopefully this will clarify the need.
I want to create an app with multiple themes - defined as SASS variables.

/dark-theme/_theme-vars.scss
/light-theme/_theme-vars.scss

When the build runs, a CSS bundle file for each theme is emitted. Each component imports the SASS file containing the theme variables @import "theme-vars.scss". I configure the includePath of the sass-loader to point to the appropriate theme directory.
The full setup is shown in the repository

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
                // 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"
        // })
    ]
};

The above config runs happily emitting the css bundle /dist/light-theme.css. I can change the includePaths variable and generate /dist/dark-theme.css.

I want to run the build once - emitting both light and dark theme bundles.
So as shown in the putative commented out code, I want to somehow create "two instances" of the MiniCssExtractPlugin. Each one configured with the appropriate theme directory path.

alexkrolick

alexkrolick commented on Mar 20, 2018

@alexkrolick

Another use case is this:

  • Vendored stylesheet imports (i.e., Bootstrap and library CSS from node_modules) should be bundled without CSS modules
  • App CSS should be bundled with modules in the loader config

In ETWP we'd do:

-const ExtractTextPlugin = require('extract-text-webpack-plugin')
+const ExtractTextPlugin = require('mini-css-extract-plugin')

-const GlobalExtractTextPlugin = new ExtractTextPlugin({
-  filename: production ? 'styles-[name]-[contenthash].css' : 'styles-[name].css',
-  ignoreOrder: false,
-  allChunks: true,
-})
-
-const ModuleExtractTextPlugin = new ExtractTextPlugin({
-  filename: production ? 'modules-[name]-[contenthash].css' : 'modules-[name].css',
-  ignoreOrder: false,
-  allChunks: true,
-})
       {
         test: /\.(css)$/,
         include: [/stylesheets/, /node_modules/],
-        use: extractCss
-          ? GlobalExtractTextPlugin.extract({
-            fallback: ['style-loader', 'css-loader'],
-            use: ['css-loader'],
-          })
-          : ['style-loader', 'css-loader'],
+        use: extractCss ? [ExtractTextPlugin.loader, 'css-loader'] : ['style-loader', 'css-loader'],
       },
      {
		 test: /\.css$/,
         exclude: [/stylesheets/, /node_modules/],
         use: extractCss
+          ? [
-          ? ModuleExtractTextPlugin.extract({
+            ExtractTextPlugin.loader,
-            fallback: [
-              'style-loader',
-              'css-loader?sourceMap&modules,localIdentName=[local]-[hash:base64]',
-            ],
+          ]
-            use: ['css-loader?sourceMap&modules,localIdentName=[local]-[hash:base64]'],
+            'css-loader?sourceMap&modules,localIdentName=[local]-[hash:base64]',
-          })
           : ['style-loader', 'css-loader?sourceMap&modules,localIdentName=[local]-[hash:base64]'],
albertstill

albertstill commented on Mar 21, 2018

@albertstill

Here is an example repo of me trying to achieve theming with multiple instances of extract-text-webpack-plugin and two seperate PostCSS configs. It compiles but no files are written to disk, be great if this library supported the use case!

garygreen

garygreen commented on Mar 27, 2018

@garygreen

Does this functionality not overlap with splitChunks? Your essentially wanting to split your different theme files? Seems to me you can just split your rules up so they generate each theme separately and use splitChunks to output them into the correct files?

james-s-turner

james-s-turner commented on Mar 27, 2018

@james-s-turner
Author

@garygreen I can't see how that would work. In the end the SASS processor has to run twice (with different variables files each time) generating parallel sets of CSS. My understanding off chunks is that it's one set of output split into different bits - rather than two separate outputs. I'd happily be proved wrong tho ;-)

garygreen

garygreen commented on Mar 27, 2018

@garygreen

@james-s-turner I'm thinking something along the lines of:

module: {
    rules: [
        {
            test: /\.scss$/,
            include: path.resolve(__home, "src/light-theme"),
            use: [
                MiniCssExtractPlugin.loader,
                "css-loader",
                "sass-loader"
            ]
        },
        {
            test: /\.scss$/,
            include: path.resolve(__home, "src/dark-theme"),
            use: [
                MiniCssExtractPlugin.loader,
                "css-loader",
                "sass-loader"
            ]
        }
    ]
},

With a splitChunks section etc.

Or is that just a slightly different way to write what your trying to achieve?

sokra

sokra commented on Mar 29, 2018

@sokra
Member

Interesting use case. The same could be supported for the mini-css-extract-plugin. In the same way as it's implemented in extract-text-webpack-plugin.

Send a PR.

james-s-turner

james-s-turner commented on Mar 30, 2018

@james-s-turner
Author

@garygreen Unfortunately if you define two rules with the same test pattern - then only the first one is run

ccorcos

ccorcos commented on Apr 12, 2018

@ccorcos

@michael-ciniawsky the goal is just to be able to create more than one CSS file. Any suggestions?

lukepolo

lukepolo commented on Apr 19, 2018

@lukepolo

We also have something like this where we have our sass styles getting extracted, then wanting to extract our vue styles to a different file.

57 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @andosteinmetz@davidli16@ErikVeland@bjankord@sokra

        Issue actions

          Support multiple instances of MiniCssExtractPlugin · Issue #45 · webpack-contrib/mini-css-extract-plugin