Why Bootstrap CSS is being bundled together with Javascript when using MiniCssExtractPlugin?

1.5k Views Asked by At

I'm trying to generate the vendors CSS and Javascript, but something is going wrong. The vendor Css is being included in both Css and Javascript bundle.

Here's my webpack configuration:

module.exports = (env) => {

  const optimization = {
    noEmitOnErrors: true,
    splitChunks: {
      cacheGroups: {
        polyfills: {
          name: 'polyfills',
          test: /polyfills|core-js|zone/,
          chunks: 'initial',
          priority: 2,
          enforce: true,
        },
        vendors: {
          name: 'vendors',
          test: /node_modules/,
          chunks: 'all',
          priority: 1,
          enforce: true,
        },
        appStyles: {
          name: 'app',
          test: (m, c, entry = 'app') => m.constructor.name === 'CssModule' && recursiveIssuer(m) === entry,
          chunks: 'all',
          enforce: true,
        },
        vendorsStyles: {
          name: 'vendors',
          test: (m, c, entry = 'vendors') => m.constructor.name === 'CssModule' && recursiveIssuer(m) === entry,
          chunks: 'all',
          enforce: true,
        }
      }
    },
  };

  return {
    optimization,
    devtool: 'source-map',
    entry: {
      app: helpers.root('/client/src/main.ts'),
      vendors: helpers.root('/client/src/vendors.ts'),
      polyfills: helpers.root('/client/src/polyfills.ts'),
    },
    output: {
      path: helpers.root('/client-dist'),
      filename: '[name].js',
    },
    resolve: {
      extensions: ['.ts', '.js'],
      modules: [
        helpers.root('/client/src'),
        helpers.root('/node_modules'),
      ],
      alias: rxPaths(),
    },
    module: {
      rules: [
        {
          test: /\.ts$/,
          use: ['ts-loader', 'angular2-template-loader'],
          include: helpers.root('/client/src'),
        },
        {
          test: /\.html$/,
          use: ['html-loader'],
          include: helpers.root('/client/src'),
        },
        {
          test: /\.css$/,
          use: [
            CssExtractPlugin.loader,
            'css-loader',
          ],
          include: helpers.root('/node_modules/bootstrap'),
        },
        {
          test: /\.less$/,
          use: [
            CssExtractPlugin.loader,
            'css-loader',
            'less-loader',
          ],
          include: helpers.root('/client/src/assets/styles'),
        },            
      ],
    },
    plugins: [
      new CleanPlugin(['client-dist'], {root: helpers.root('/')}),
      new webpack.LoaderOptionsPlugin({debug: true}),
      new webpack.ContextReplacementPlugin(/@angular\/core\/fesm5/, helpers.root('/client/src')),
      new webpack.optimize.ModuleConcatenationPlugin(),
      new CssExtractPlugin({filename: 'assets/styles/[name].css'}),
      new HtmlPlugin({template: helpers.root('/client/src/index.html')}),
    ],
  };
};

And this is the vendors.ts entry:

import 'bootstrap/dist/css/bootstrap.min.css';

This results in a vendors.css including bootstrap.min.css, but bootstra.min.css is also included in vendors.js. How can I separate this?

2

There are 2 best solutions below

2
On

OK, it seems to be a bug in Webpack bundle analyzer tool I'm using to check the bundles.

enter image description here

But bootstrap.min.css was removed from the vendor.js:

enter image description here

0
On

I figured out my issue. For css-loader I had modules set to true which caused the bootstrap css to be added to the JavaScript vendor file.

{
    test: /\.s?[ac]ss$/,
    use: [
        MiniCssExtractPlugin.loader,
        {
            loader: 'css-loader',
            options: {
                modules: false, // If this is true then I see the issue
                camelCase: 'dashes',
                minimize: isProduction,
                sourceMap: !isProduction,
            }
        },
        {
            loader: 'sass-loader',
            options: {
                sourceMap: !isProduction
            }
        },
    ]
}