How to extract each css/scss file in the application into a separate css files with splitChunks plugin?

30 views Asked by At

I have an express/nest application where I create react templates, and for assembly I use webpack.

As part of my task, there was a need to distinguish between files in order to be able to allocate separate files in the dist folder for certain files.

That is, instead of just 1 common main.css (not counting the files that are created for libraries), I want to be able to create other files.

Exprected retult:

dist
 -main.css
 -other1.css
 -other2.css

I need this for the reason that I import some global styles, such as page for pdf, which is global but may differ from case to case.

@page {
      size: A4;
    }

Here is my webpack config:

const nxConfig = require('@nrwl/react/plugins/webpack')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const autoprefixer = require('autoprefixer')

module.exports = (config) => {
  nxConfig(config)

  config.node = {
    global: true,
  }

  const postcssLoader = {
    loader: 'postcss-loader',
    options: {
      postcssOptions: {
        plugins: [autoprefixer],
      },
    },
  }

  const rawCssLoader = {
    loader: 'raw-css-loader',
  }

  let isFontsAdded = false
  const sassLoader = {
    loader: 'sass-loader',
    options: {
      additionalData: (content) => {
        if (!isFontsAdded) {
          isFontsAdded = true
          return '@import "libs/assets/theme/fonts/index.scss";' + content
        }
        return content
      },
    },
  }

  config.module.rules.push({
    test: /\.css$|\.scss$|\.sass$/,
    oneOf: [
      {
        test: /\.module\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: 'css-loader',
            options: {
              modules: {
                localIdentName: '[local]--[hash:base64:5]',
              },
              importLoaders: 1,
            },
          },
          postcssLoader,
        ],
      },
      {
        test: /\.module\.(scss|sass)$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: 'css-loader',
            options: {
              modules: {
                localIdentName: '[local]--[hash:base64:5]',
              },
              importLoaders: 3,
            },
          },
          postcssLoader,
          'resolve-url-loader',
          sassLoader,
        ],
      },
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, rawCssLoader, postcssLoader],
      },
      {
        test: /\.scss$|\.sass$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: 'css-loader',
            options: {
              importLoaders: 2,
              modules: {
                compileType: 'icss',
                localIdentName: '[local]--[hash:base64:5]',
              },
            },
          },
          postcssLoader,
          'resolve-url-loader',
          sassLoader,
        ],
      },
    ],
  })

  config.plugins.push(
    new MiniCssExtractPlugin({
      filename: '[name].css',
      chunkFilename: '[id].css',
    })
  )

  // load css assets
  config.module.rules.push({
    test: /\.(png|jpe?g|gif|svg|eot|ttf|woff|woff2)(\?.*)?$/i,
    issuer: /(?<!module)\.scss$|\.sass$/,
    type: 'asset/inline',
  })

  config.module.rules.push({
    test: /\.(png|jpe?g|gif|svg|eot|ttf|woff|woff2)(\?.*)?$/i,
    issuer: /\.scss$|\.sass$/,
    type: 'asset/inline',
  })

  return config
}

I also tried to use split chunks plugin for this, but I cant catch all css fils inside(

 config.optimization = {
    splitChunks: {
      cacheGroups: {
        commons: {
          test: /[\\/]node_modules[\\/]/,
          // cacheGroupKey here is `commons` as the key of the cacheGroup
          name(module, chunks, cacheGroupKey) {
          
            //CHECK CERTAIN CSS CHINKS HERE
            
            const moduleFileName = module
              .identifier()
              .split('/')
              .reduceRight((item) => item)
            const allChunksNames = chunks.map((item) => item.name).join('~')
            return `${cacheGroupKey}-${allChunksNames}-${moduleFileName}`
          },
          chunks: 'all',
        },
      },
    },
  }

Or, I would even rephrase the question like this:

Is it possible to split the existing main chunk, which produces the main.css file for us, into multiple chunks in the dist folder with split plugin? In other words, instead of having just main.css, can we have main.css and other.css?

And I can't use lazy loading here, since teplate is genereted on server side(

0

There are 0 answers