Webpack Code Splitting - Prevent Duplicate CSS File in Build
Asked Answered
R

2

6

I've bootstrapped my app with Create-React-App version 3.4.1 and am using Craco version 5.6.4 to make modifications to the Webpack config CRA provides. Due to specific client expectations which are out of my control, I need to end up with build/js/main.js and build/css/main.css file structure. I've managed to, with Craco, modify the file output as desired, except that I end up with an additional copy of the CSS file with the chunk hash added.

Here's my craco.config.js:

const { POSTCSS_MODES } = require('@craco/craco');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  style: {
    postcss: {
      mode: POSTCSS_MODES.file,
    },
  },
  webpack: {
    configure: {
      optimization: {
        splitChunks: {
          cacheGroups: {
            default: false,
          },
        },
        runtimeChunk: false,
      },
      plugins: [
        new webpack.optimize.LimitChunkCountPlugin({
          maxChunks: 1,
        }),
        new MiniCssExtractPlugin({
          filename: 'css/[name].css',
        }),
      ],
      output: {
        filename: 'js/[name].js',
      },
    },
  },
};

And here's what's being output when I run yarn build:

...

Creating an optimized production build...
Compiled successfully.

File sizes after gzip:

  60.31 KB  build/js/main.js
  66 B      build/static/css/main.0cb9b881.css
  57 B      build/css/main.css

...

(Yes, the CSS file presently has no rules in it, which explains its small size.)

My goal is to eliminate creation of that second file, build/static/css/main.0cb9b881.css.

I've tried numerous alterations to my config, including https://github.com/webpack-contrib/mini-css-extract-plugin#extracting-all-css-in-a-single-file, to no avail. I'm able to generate the CSS file I want using MiniCssExtractPlugin to specify a filename, and to generate the single JS bundle using the standard Webpack output filename. This is a non-ejected CRA-generated app, so I'm guessing there's some mechanism inside the built-in Webpack config that's generating that extra file and that I just need to override that in my Craco config. If anyone knows precisely which bit needs to be overridden, I'd greatly appreciate the help!

Rubrician answered 26/8, 2020 at 19:3 Comment(0)
G
0

In fact, there are already two "MiniCssExtractPlugin" objects in your webpack configuration. You only need to change the "filename" attribute of the original "MiniCssExtractPugin" to "static/cs s/[name]. css" instead of adding the "MiniCssExtractPlugin" object.

Granulocyte answered 18/10, 2022 at 5:26 Comment(0)
C
0

I had the same problem, and it took me a while to understand @miniphper's answer. Here's a concrete example how to do it - just for MiniCssExtractPlugin, the other configuration changes (optimization, LimitChunkCountPlugin, output.filename) are not included.

Instead of adding a new instance of the plugin, you need to search the existing plugins and modifiy it's options:

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

module.exports = () => {
  return {
    webpack: {
      configure: (webpackConfig) => {
        const miniCssExtractPlugin = webpackConfig.plugins.find(
          webpackPlugin => webpackPlugin instanceof MiniCssExtractPlugin 
        );
        if (miniCssExtractPlugin) {
          miniCssExtractPlugin.options.filename = 'css/[name].css';
        }

        // For the other configuration changes modify `webpackConfig`. E.g.:
        // webpackConfig.output.filename = 'js/[name].js';

        return webpackConfig;
      },
    },
  };
};
Climacteric answered 16/11, 2022 at 9:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.