7

I need to create multiple theme CSS files using webpack version 4 and "mini CSS extract plugin" in my react project. Depends on a place where webpack will find an import of the SCSS file, it should use loader twice - with different data in sass-loader options.

I found nothing useful in the Internet according this goal. I also have already tried to use such webpack's loaders as: webpack-combine-loaders, multi-loader etc...

here is a part of webpack config

module: {
  rules: [
    {
       test: /\.scss$/,
       use: [
         {
           loader: MiniCssExtractPlugin.loader,
         },
         'css-loader',
         {
            loader: "sass-loader",
            options: {
               data: '$theme: dark;',
            }
         },
       ],
     },
     { // the same except data in options
       test: /\.scss$/,
       use: [
         {
           loader: MiniCssExtractPlugin.loader,
         },
         'css-loader',
         {
            loader: "sass-loader",
            options: {
               data: '$theme: white;',
            }
         },
       ],
     },
  ],
},
plugins: [
  new MiniCssExtractPlugin({
    filename: 'client.white.css',
  }),
  new MiniCssExtractPlugin({ 
    filename: 'client.dark.css',
  }),
],

and in my scss file (button.scss) I use such condition:

$background: #06cc1a;
$color: white;

@if $theme == dark {
  $background: white;
  $color: black;
}

.button {
    background-color: $background;
    color: $color;
  }
}

as a result, I want to get two CSS files client.white.css where were applied sass variables for the white theme and client.dark.css where were applied variables for the dark theme

Avrel Dusop
  • 135
  • 3
  • 11

2 Answers2

4

We solved this in our project by using multiple entry points, one for each theme, e.g:

entry: {
    light: './src/css/light.scss',
    dark: './src/css/dark.scss'
}

With the contents of light.scss files being as follows:

$background: #001560;    

@import "~base/scss/base.scss";

Webpack will output a single css file for each theme containing all the styles, both base and theme-specific, which is great when optimising for production.

Note though that you will also get a redundant JS file, which you may want to clean up post-build.

Peter
  • 280
  • 2
  • 9
0

I worked on a web app which use multi theme, and we tackle the problem by saving each theme's colors to backend, so we can get the value from API depending from query, and for styling, we use styled-components for that.

I find css-in-js is really useful in this kind of problem. We actually use both styled components and LESS css for our styling. styled-components are used for coloring based on theme, and the rest is on LESS css. Perhaps you can try to use that too, or even a inline css should do the work since JS variable would work on that.

A specific example is to build a ThemeProvider component that engulf the whole application as its child, ThemeProvider will contain the declaration of class with the use of styled-components and that class can be reused throughout application scope.

mfakhrusy
  • 1,128
  • 1
  • 11
  • 20