Search code examples
javascriptcsswebpacksasswebpack-5

Repeat the same rules for different files in webpack


I have webpack.config.js file that has the same set of rules repeated for different SCSS files.

For example within the rules:

module.exports = {
  module: {
    rules: [
      // in here
    ]
  }
}

I have a src/styles/templates/cart.scss file that outputs to template.cart.css:

      {
        test: /cart\.s[ac]ss$/i,
        include: [
          path.resolve(__dirname, "src/styles/templates/cart.scss")
        ],
        use: [
          {
            loader: 'file-loader',
            options: {
              name: 'template.cart.css',
            }
          },
          {
            loader: 'extract-loader'
          },
          {
            loader: 'css-loader',
            options: {
              url: false
            },
          },
          {
            loader: 'postcss-loader'
          },
          {
            loader: 'sass-loader',
            options: {
              sourceMap: false,
              sassOptions: {
                outputStyle: 'compressed'
              },
            },
          },
        ],
      },

Then I have the same thing for src/styles/templates/account.scss into template.account.css:

      {
        test: /account\.s[ac]ss$/i,
        include: [
          path.resolve(__dirname, "src/styles/templates/account.scss")
        ],
        use: [
          {
            loader: 'file-loader',
            options: {
              name: 'template.account.css',
            }
          },
          {
            loader: 'extract-loader'
          },
          {
            loader: 'css-loader',
            options: {
              url: false
            },
          },
          {
            loader: 'postcss-loader'
          },
          {
            loader: 'sass-loader',
            options: {
              sourceMap: false,
              sassOptions: {
                outputStyle: 'compressed'
              },
            },
          },
        ],
      },

This is repeated 10+ times for different files.

Is there a way to streamline this rather than repeating the same large chunk of code for each file pair?


Solution

  • I forgot to answer this once I found the solution.

    @Martin sent me in the right direction. I misunderstood the use of MiniCssExtractPlugin.

    The solution in this case was to include the MiniCssExtractPlugin:

    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    

    Then use in in the rule with a more general test:

          {
            test: /.s[ac]ss$/i,
            use: [
              {
                loader: MiniCssExtractPlugin.loader
              },
              {
                loader: 'css-loader',
                options: {
                  url: false
                },
              },
              {
                loader: 'sass-loader',
                options: {
                  sourceMap: false,
                  sassOptions: {
                    outputStyle: 'compressed'
                  },
                },
              },
            ],
          },