Vue and Webpack tree shaking, sideEffects and CSS: CSS of unused components being loaded

Viewed 3277

We are trying to figure out the correct way of handling tree shaking for CSS in Vue Single File Components with Webpack.

In package.json, I have: "sideEffects": ["*.css", "*.less","*.vue" ], this seems to be working properly for stopping Vue components from loading when they shouldn't be. However, every single <style> tag from the SFCs is been loaded on the page.

How we are loading our SFC is from a NPM package that list a bunch of exports, like

export blah from 'blah.vue';
export blah2 from 'blah2.vue';
export blah3 from 'blah3.vue';

Even if in our JavaScript I have just import { blah3 } from 'a-npm-package'; it is including the styles from all three. Since we have a quite a few Vue components this is leading to a lot of unused CSS being added to the page.

How can we prevent this? There has to be a better more dynamic way of handling styles rather than just dumping them all into the page even if only 1/10th of them is being used?

Thanks

3 Answers

You can use MiniCssExtractPlugin to tree shake CSS. Also if you're using scss or sass, you can add those loaders as well.

// webpack.config.js (production)
const path = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

module.exports = {
  mode: 'production',

  entry: path.resolve('src/index.js'),

  output: {
    filename: '[name].js',
    path: path.resolve('dist'),
  },

  module: {
    rules: [
      {
        test: /\.jsx?$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
      },
      {
        test: /\.css$/,
        exclude: /node_modules/,
        use: [
          // Extract the css to file
          MiniCssExtractPlugin.loader,
          // Handle import of `.css` files in your app
          'css-loader',
        ],
      },
    ],
  },
  plugins: [
    // Extract all css into a separate file
    new MiniCssExtractPlugin({
      filename: '[name].css',
    }),
  ],
}
Related