Webpack is importing CSS of other bundles

688 views Asked by At

I have a Webpack setting to build different bundles and put all the CSS used by the bundle in a CSS file.

The problem is that Webpack is putting all the CSS of all the bundles together.

Mi project is configured in the following way.

webpack.config.js

module.exports = {
  entry: {
    'bundle-a': './src/bundle-a.ts',
    'bundle-b': './src/bundle-b.ts'
  },
  ...
  plugins: [
    new MiniCssExtractPlugin(),
  ],
  module: {
    rules: [
      {
        test: /\.ts(x?)$/,
        include: path.resolve(__dirname, 'src'),
        use: ['ts-loader']
      },
      {
        test: /\.css$/,
        include: path.resolve(__dirname, 'src'),
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: 'css-loader',
            options: {
              modules: 'local'
            }
          }
        ]
      }
    ]
  }
};

src/bundle-a.ts

import style from './bundle-a.css';

...

src/bundle-a.css

.class-bundle-a {
  ...
}

src/bundle-b.js

import style from './bundle-b.css';

...

src/bundle-b.css

.class-bundle-b {
  ...
}

When I build the project I get the following CSS files.

dist/bundle-a.css

.class-bundle-a {
  ...
}

.class-bundle-b {
  ...
}

dist/bundle-b.css

.class-bundle-a {
  ...
}

.class-bundle-b {
  ...
}

I expect that the dist/bundle-a.css only have the CSS imported in the src/bundle-a.ts, but also I am getting the CSS imported by the src/bundle-b.ts, and the same pass with the src/bundle-b.css. The same happens if I use style-loader.

I want to know if this is the expected behavior or I have some error in my code.

2

There are 2 answers

0
tom On

You can add an additional rule. It's a bit redundant but works for me:

module.exports = {
    entry: {
        'bundle-a': './src/bundle-a.ts',
        'bundle-b': './src/bundle-b.ts'
    },
    // ...
    module: {
        rules: [
            // ...
            {
                test: /bundle-a\.(sa|sc|c)ss$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader,
                    },
                    'css-loader',
                    'postcss-loader',
                    'sass-loader',
                ],
            },
            {
                test: /bundle-b\.(sa|sc|c)ss$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader,
                    },
                    'css-loader',
                    'postcss-loader',
                    'sass-loader',
                ],
            },
            // ..
        ]
    },
    optimization: { 
        // ...
    },
    plugins: [
        // ...
    ]
};
0
Felipe Malara On

You can try using the postcss loader with the cssnano too.

The objective of that is to optimize your css files import.

One of the cssnano optimizations is to discard duplicates cssnano#discardDuplicates

You can try using like this in your webpack.config.js:

...
rules: [
  ...
  {
    test: /\.css$/i,
    exclude: /node_modules/,
    use: [
      {
        loader: MiniCssExtractPlugin.loader,
        options: {
          publicPath: path.resolve(__dirname, '../dist/css/')
        }
      },
      {
        loader: 'css-loader',
        options: {importLoaders: 1},
      },
      {
        loader: 'postcss-loader',
        options: {
          postcssOptions: {
            config: path.resolve(__dirname, 'postcss.config.js'),
          },
        },
      },
    ],
  },
  ...

And create a file for your postcss ( postcss.config.js ) like this:

module.exports = {
  plugins: {
    'cssnano': {
      autoprefixer: { add: true },
      discardComments: { removeAll: true },
      discardDuplicates: true,
      discardEmpty: true,
      discardOverridden: true,
      discardUnused: true,
      reduceIdents: false,
      reduceInitial: false,
      reduceTransforms: false,
      zindex: false
    }
  }
}