marcusds
marcusds

Reputation: 794

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

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

Upvotes: 14

Views: 4925

Answers (3)

Tom King
Tom King

Reputation: 104

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',
    }),
  ],
}

Upvotes: 1

Tom King
Tom King

Reputation: 104

If components are only sometimes needed, then lazy-loading them is a good way to reduce clutter.

ex:

const MyComponent = () => import(/* webpackChunkName: "MyComponent" */'../components/MyComponent');

https://vuedose.tips/dynamic-imports-in-vue-js-for-better-performance/

You could also incorporate plugins into your Webpack config to help manage bulky code, such as MiniCSSExtractPlugin, in this case.

Upvotes: 0

LastM4N
LastM4N

Reputation: 2230

What if you use lazy loading components?

The components with the style tag will be loaded only when it's needed.

You can do the same for routes with the lazy loading routes.

Upvotes: 0

Related Questions