vuetify-module icon indicating copy to clipboard operation
vuetify-module copied to clipboard

[Bug] TreeShaking not working properly (src is included in bundle)

Open AbdallahAlhaddad opened this issue 4 years ago • 13 comments

Modules versions

"nuxt": "^2.14.0"
"@nuxtjs/vuetify": "^1.11.2",

Bug description When building for production, nuxtjs/vuetify module doesn't properly apply tree-shaking as it includes the src directory in the final bundle.

To Reproduce

  • Create the default nuxt/vuetify project (using npx create-nuxt-app <project-name> then select vueitfy as a framework).

  • Run the command: npx nuxt build --analyze

  • You will see the vuetify module in app.[hash].js file with approximate size of 406 kb as src directory is also included.

  • Vuetify size in nuxt app (406 kb): nuxt

Expected behavior Only the used components should be included in the final bundle (Only lib directory should be found in vuetify module, i.e. src should not be included.) as in the official vuetify module in normal Vue SPA project.

  • Vuetify size in normal SPA app (85.64 kb): vue

AbdallahAlhaddad avatar Sep 06 '20 20:09 AbdallahAlhaddad

Having a similar issue with the latest version. Below is the default template created by create-nuxt-app.

WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
This can impact web performance.
Assets: 
  app.9e69a9c.css (334 KiB)

config

  • mode: spa
  • target: static
  • extractCSS: true
  • treeShake: true

kamikazechaser avatar Sep 10 '20 08:09 kamikazechaser

While I'm trying to find a solution, I found this project and if you analyze it, you will find that when vuetify is added manually, there is no problem with treeshaking !

https://github.com/csheppard/nuxt-vuetify-loader

Barbapapazes avatar Sep 13 '20 09:09 Barbapapazes

Any updates on this @Barbapapazes ?

bitbytebit1 avatar Sep 21 '20 15:09 bitbytebit1

No, try so many things on this project (nuxt/vuetify) and just find that the vuetify-loader-plugin doesn't work as expected here but well outside so I will continue my investigation! 😉

Barbapapazes avatar Sep 21 '20 15:09 Barbapapazes

@Barbapapazes fyi the project you linked doesn't have this issue because it's using vuetify v1. v2 was a complete rewrite.

dflupu avatar Sep 21 '20 19:09 dflupu

I`l check whats happening here

aldarund avatar Dec 02 '20 00:12 aldarund

This isn't a bug, only sass is being loaded from src. The bundle analyzer will show different results depending on if mini-extract-css-plugin is used.

KaelWD avatar Dec 02 '20 07:12 KaelWD

@KaelWD The main.sass is still large, always > 450 Kib in most builds I have seen from other users (#342). I am not familiar with with the internals, but could this be somehow solved? (with say some loader option?).

kamikazechaser avatar Jan 16 '21 18:01 kamikazechaser

@kamikazechaser I hacked around this. I wrote a simple parser that reads my css and removes styles I know (but vuetify can't know) are not needed. YES this is a hack and not the best solution but I removed a LOT of CSS.

For me I removed all .v-application--is-rtl, [dir=rtl], .theme--dark . (Some more stuff but that was the biggest CSS Chunk. My Website is in German so no need for rtl and we only have one theme so no theme-dark needed.

But again DO NOT USE THIS as this is not a good way to do this stuff!!

mathe42 avatar Jan 16 '21 18:01 mathe42

@mathe42 I tried purgeCSS, it does work. But it can severely break a large application. Its also tedious since you have to handpick and add regex to the safelist. Let me see if I can come up with a safe configuration. I have seen some people try this FullHuman/purgecss#67. This looks unsafe. Its better to use extractCSS: true and use the CLI on the produced CSS.

Another solution could be this.

kamikazechaser avatar Jan 16 '21 19:01 kamikazechaser

Basicly my function look like this:

function handleContents(content) {
  return content
    .split('}')
    .filter((v) => {
      const sel = v.split('{')[0]
      return sel
        .split(',')
        .every(
          (selector) =>
            !selector.includes('.v-application--is-rtl') &&
            !selector.includes('[dir=rtl]') &&
            !selector.includes('.theme--dark')
        )
    })
    .join('}')
}

mathe42 avatar Jan 16 '21 20:01 mathe42

You might also consider parsing through all your vue components to find which Vuetify Atomic CSS helpers are used and removed all those that aren't. I wrote a script you'd need to use in conjunction with purgecss/css-byebye here

t1mwillis avatar Jan 21 '21 17:01 t1mwillis

Basicly my function look like this:

function handleContents(content) {
  return content
    .split('}')
    .filter((v) => {
      const sel = v.split('{')[0]
      return sel
        .split(',')
        .every(
          (selector) =>
            !selector.includes('.v-application--is-rtl') &&
            !selector.includes('[dir=rtl]') &&
            !selector.includes('.theme--dark')
        )
    })
    .join('}')
}

@mathe42 could you please help, where did you put this code in your nuxt project?

VladBrok37 avatar Jul 26 '23 19:07 VladBrok37