nuxt-community / vuetify-module

Vuetify Module for Nuxt 2
Other
628 stars 106 forks source link

Vuetify with tree shake enabled in SSR doesn't render property #208

Open vishr opened 4 years ago

vishr commented 4 years ago

Module version 1.9.0

Describe the bug If I enable treeShake the page rendered via SSR isn't display properly.

To Reproduce I have attached a sample project. nuxtjs-vuetify.zip

Steps to reproduce the behavior:

  1. yarn && yarn build && yarn start
  2. From the browser you will see a flicker before it renders properly
  3. You can also do curl http://localhost:3000 > /tmp/out.htm and open to see the file

Expected behavior The SSR version should be same as client

Screenshots

Screen Shot 2019-10-30 at 12 49 11 PM Screen Shot 2019-10-30 at 12 49 00 PM
enddevNZ commented 4 years ago

TreeShake worked when i enabled it on your example project.

However, try add extractCSS to the build property. With not extracting, all of the CSS gets injected into the head on every load from the vendor.js which is why that flickering will be prominent.

MuhaddiMu commented 4 years ago

Any idea why tree shake takes alot of time at initial rendering as compared to when tree shake is disabled?

kevinmarrec commented 4 years ago

@vishr Is it fixed with extractCSS ? If no when I'm not sure how to help, it would be more likely Nuxt issue and not specific to this module.

kevinmarrec commented 4 years ago

@MuhaddiMu Not sure what you are talking about, with https://github.com/nuxt-community/vuetify-module/releases/tag/v2.0.0-alpha.0 , there is no way to not use treeShaking. Vuetify is treeshakable by default and you shouldn't use dist/vuetify.js + dist/vuetify.css which was possible with treeShake: false before.

slipros commented 4 years ago

@vishr check that - https://github.com/nuxt-community/vuetify-module/issues/210#issuecomment-549203258

adrienbaron commented 4 years ago

I'm currently investigating the same issue. From what I gathered so far when using treeShake generated style blocks don't get integrated in the SSR result. Using treeShake: false will integrate all Vuetify CSS in the page as a style tag (which we definitely don't want!). Finally the solution pointed out by @SLIpros (using extractCSS) seems to add all the CSS from Vuetify in an external CSS file and load that. We get styles with no JS enabled (Yay!) but we still ship way too much CSS :(. According to Vue Style Loader doc there should be a way to make it inject those style during SSR (which would be best of both world, minimal amount of CSS shipped + instant style without having to wait for JS to kick in). Not sure yet which project this change will impact though, so I'll keep investigating 🔎 ! If I figure out a solution I'll try to open a PR in the relevant project 👍

enddevNZ commented 4 years ago

Finally the solution pointed out by @SLIpros (using extractCSS) seems to add all the CSS from Vuetify in an external CSS file and load that.

From my understanding if your treeShake is enabled and working correctly, extractCSS will only pull out the css from the vendor.js that your treeShake has gathered. I have a project and it is working like this for me.

We get styles with no JS enabled (Yay!) but we still ship way too much CSS

I'd suggest doing a npm run build -- -a to check that the vuetify bundle is showing in your vendor.js.

adrienbaron commented 4 years ago

@enddevNZ Indeed, my bad, it does seem to only include the CSS for what's being used in the app, which is much better that what I first thought! However it only include styles for components that end up in the bundle, so components that are used only on a page for example, and would only be in this page bundle will still not have style on SSR (and get it when the bundle for that page loads). Moreover you still might have to load a bit more CSS than necessary (some components might make it to the bundle, but not be used on the actual page you are on, albeit that's probably an edge case :)). The manualInject option from vue-style-loader looks promising though, as it seems to state explicitly that style from non .vue files (which is the case for Vuetify components) would only get bundled in JS and not added to SSR unless you use that option and wire things up. So maybe there is something there 👍

adrienbaron commented 4 years ago

Ok, I found a way to make it work 👍. Sadly it would require quite a few changes in Vuetify :(.

Basically we first would need to change Vuetify components like so:

// Name the styles import
import styles from './VCard.sass'

/* @vue/component */
export default mixins(
  Loadable,
  Routable,
  VSheet
).extend({
  // Add a beforeCreate hook that inject the styles if presents
  beforeCreate() {
    if(styles.__inject__) {
      styles.__inject__(this.$ssrContext)
    }
  },
  // ...
})

Then in Nuxt config you ask the vueStyle loader to use manualInject:

  /*
   ** Build configuration
   */
  build: {
    loaders: {
      vueStyle: { manualInject: true }
    }
  }

When doing so, the style get's injected in the SSR context correctly 👍. This behaviour from vue-style-loader only applies for SSR mode, the client still behaves the same (see here for client and here for server)

If manualInject is not set to true, then the current behaviour applies and styles.__inject__ is undefined so the beforeCreate hooks doesn't do anything.

This change would add that hook to every component though so it's still has a bit of a performance hit (even though it's just calling a function that immediately returns). Maybe we could find a way for that hook to be defined when running on the server? Also there is the matter of functional components that cannot have lifecycle hooks, not sure what we could do for those :(.

Anyway that should probably move the the Vuetify repository if we want to take this further 👍

freddy38510 commented 4 years ago

@adrienbaron Well spotted ! How could we add this hook to the framework of vuetify which import the main style ?

adrienbaron commented 4 years ago

@freddy38510 thanks! I think the only way for this to work is to add this hook to every Vuetify components with a PR there. I’ve asked for opinions on their discord, waiting for feedback before proceeding with doing the PR if everything looks OK for them

freddy38510 commented 4 years ago

@adrienbaron i talked about the style "main.sass" imported from this file. As soon as "manualInject" is enabled, all styles imported from vuetify need to be injected manually. Not only those from components.

We could also use the module nuxt-purgecss to improve performance. These options seems to work fine:

purgeCSS: {
  mode: 'postcss',
  paths: [
    'node_modules/vuetify/src/**/*.ts'
  ],
}

Of course, some selectors should be whitelisted.

adrienbaron commented 4 years ago

@freddy38510 good shout! Yes we would need to figure something out for the main style, I didn’t see it :)! For nuxt purge css you mean to drop unused CSS from the style that are injected in the SSR page?

freddy38510 commented 4 years ago

@adrienbaron Yeah that's right! The unused CSS is also dropped from js files.

I just did a comparison with and without purged CSS on a basic template of Vuetify with a Card component in content.

Without purged CSS: not purged

With purged CSS: purged

vishr commented 4 years ago

@vishr Is it fixed with extractCSS ? If no when I'm not sure how to help, it would be more likely Nuxt issue and not specific to this module.

Not really. The issue still exists.

kevinmarrec commented 4 years ago

@adrienbaron Thank for your time investigating, so from your POV it seems that it's overall Vuetify components that would have a SSR issue ?

EDIT : Succeeded to reproduce it without Vuetify, but it's related of how Vuetify components are handling css (importing the css in js) : https://github.com/kevinmarrec/nuxt-css-issue

DispatchCommit commented 4 years ago

Super lazy workaround, add to nuxt.config

css: [
    'vuetify/dist/vuetify.css',
],

It's a heavy-handed overkill workaround, but it prevent some massive page reflowing I was having on load, so it's a trade off of a fast load time that feels sluggish, and broken, and a slower load time that looks snappier. Combining this with @nuxtjs/device to target mobile / desktop separately for a best SSR 'look' is worth the increase to me.

kevinmarrec commented 4 years ago

@DispatchCommit You don't have double css ?

DispatchCommit commented 4 years ago

@kevinmarrec No I do get duplicated CSS for some styles, so it's not ideal, but it's functional for now until we get a better a better solution for the bug you've pointed out above.

GarciaTandela commented 4 years ago

ScreenShot_20200516153645 ScreenShot_20200516153519

I guys, i'm having the same problem with my web app. When i run in development the page runs well and don't take long for css styles been applied. But when when it goes to production this is what happens, the styles takes time for come then it loads well. Can anyone tell me why is having this behavior ?

GarciaTandela commented 4 years ago

First i though it was a problem with vuetify version i tried to update it, but it didn't solve anything. I'm really needing for a solution

adrienbaron commented 4 years ago

@YannickSilva It's possible you have the same problem, meaning SSR doesn't include styles.

I see 2 choices for now:

First you need to update your package.json to use the version of vuetify-loader that include my patch:

"vuetify-loader": "git+https://github.com/adrienbaron/vuetify-loader.git"

Then it requires to change a bit of configuration depending on the version of Vuetify Nuxt module you are using.

Here is an example nuxt.config.js with @nuxtjs/vuetify v1.x:

export default {
  // ...
  build: {
    loaders: {
      vueStyle: { manualInject: true }
    }
  },
  vuetify: {
    treeShake: {
      loaderOptions: { registerStylesSSR: true }
    }
  }
}

For @nuxtjs/vuetify v2.x the way you pass options to vuetify-loader has changed:

// nuxt.config.js
export default {
  // ...
  build: {
    loaders: {
      vueStyle: { manualInject: true }
    }
  },
  vuetify: {
    loader: {
      registerStylesSSR: true
    }
  }
}

Finally, when using manualInject in Nuxt.js, the css block from nuxt.config.js will not work. Instead, you will need import your own stylesheets in thestyle block of your default template for it to be picked up by vue-style-loader.

For example like so:

<!-- default.vue -->
<style lang="stylus">
@import "../assets/style/app.styl"
</style>
GarciaTandela commented 4 years ago

@adrienbaron the problem is that i really need the SSR working because of SEO, and for the second option if isn't well tested i would go for it, so i can not have problem in the future. But i have another question if i use the Tag would it affect my page SEO ?

adrienbaron commented 4 years ago

@YannickSilva if you use the second option it shouldn't affect SEO :). I use it on: https://www.clashofstats.com/ if you want to checkout how it behaves

GarciaTandela commented 4 years ago

@adrienbaron thanks, i will give it a try. Them i will tell you something, thanks for the help

GarciaTandela commented 4 years ago

@adrienbaron i don't understand how i will install your npm package, should i copy paste your package.json or something ? There no command for installing it

adrienbaron commented 4 years ago

@YannickSilva basically the PR is currently open, when it's merged and a new version of vuetify-loader is released it will just require updating to it (probably it will be done inside the dependencies of vuetify-module). In the meantime, NPM has a feature where you can use a git branch as a dependency. So what you can do is in your package.json devDependencies add:

"vuetify-loader": "git+https://github.com/adrienbaron/vuetify-loader.git"

The update your dependencies. Your project should then use the version of vuetify-loader with my changes 👍 .

GarciaTandela commented 4 years ago

Thanks @adrienbaron

JosephSaw commented 4 years ago

Ok, I found a way to make it work 👍. Sadly it would require quite a few changes in Vuetify :(.

Basically we first would need to change Vuetify components like so:

// Name the styles import
import styles from './VCard.sass'

/* @vue/component */
export default mixins(
  Loadable,
  Routable,
  VSheet
).extend({
  // Add a beforeCreate hook that inject the styles if presents
  beforeCreate() {
    if(styles.__inject__) {
      styles.__inject__(this.$ssrContext)
    }
  },
  // ...
})

Then in Nuxt config you ask the vueStyle loader to use manualInject:

  /*
   ** Build configuration
   */
  build: {
    loaders: {
      vueStyle: { manualInject: true }
    }
  }

When doing so, the style get's injected in the SSR context correctly 👍. This behaviour from vue-style-loader only applies for SSR mode, the client still behaves the same (see here for client and here for server)

If manualInject is not set to true, then the current behaviour applies and styles.__inject__ is undefined so the beforeCreate hooks doesn't do anything.

This change would add that hook to every component though so it's still has a bit of a performance hit (even though it's just calling a function that immediately returns). Maybe we could find a way for that hook to be defined when running on the server? Also there is the matter of functional components that cannot have lifecycle hooks, not sure what we could do for those :(.

Anyway that should probably move the the Vuetify repository if we want to take this further 👍

@adrienbaron thanks for your time in coming up with a workaround!

I am trying to follow your process and make the changes in @/vue/component but it seems that such a file doesn't exist for me, I have tried looking through "component-compiler-utils" but I am not sure if that is the one...

image

adrienbaron commented 4 years ago

@JosephSaw I actually came up with another fix for this, it takes the form of an MR on Vuetify Loader, it sadly hasn’t been merged yet, but you can try to use my version if you want to: https://github.com/vuetifyjs/vuetify-loader/pull/126

asennoussi commented 4 years ago

What @adrienbaron said, or you guys can include that CSS in layouts/default.vue. It always loads the CSS SSR

dor272 commented 4 years ago

@adrienbaron Hi, I'm trying to use your vuetify-loader fix. I added "vuetify-loader": "git+https://github.com/adrienbaron/vuetify-loader.git" to the package.json file that at the root of the project. added to nuxt config:

  build: {
    loaders: {
      vueStyle: { manualInject: true }
    }
  }
``
and

vuetify: { treeShake: { loaderOptions: { registerStylesSSR: true } }, } ``

but when I try to build I get errors:

ERROR in ./layouts/default.vue Module not found: Error: Can't resolve 'vuetify/srccomponentsVAppBarVAppBar.sass' in 'C:\Projects\proj\layouts' @ ./layouts/default.vue 55:4-58 @ ./.nuxt/App.js @ ./.nuxt/index.js @ ./.nuxt/server.js @ multi ./node_modules/@nuxt/components/lib/installComponents.js ./.nuxt/server.js

ERROR in ./layouts/default.vue Module not found: Error: Can't resolve 'vuetify/srccomponentsVAppVApp.sass' in 'C:\Projects\prices-front\layouts' @ ./layouts/default.vue 53:4-52 @ ./.nuxt/App.js @ ./.nuxt/index.js @ ./.nuxt/server.js @ multi ./node_modules/@nuxt/components/lib/installComponents.js ./.nuxt/server.js

ERROR in ./layouts/default.vue Module not found: Error: Can't resolve 'vuetify/srccomponentsVAvatarVAvatar.sass' in 'C:\Projects\prices-front\layouts' @ ./layouts/default.vue 72:4-58 @ ./.nuxt/App.js @ ./.nuxt/index.js @ ./.nuxt/server.js @ multi ./node_modules/@nuxt/components/lib/installComponents.js ./.nuxt/server.js

I'm building on Windows, and it seems like it is not building the path to the sass files of vuetify's components.

adrienbaron commented 4 years ago

@dor272 hi! I didn’t test on Windows so it is possible 😔, the PR has been merged in the main repo but not released yet, feel free to try and fix it and open a PR for that 👍

dor272 commented 4 years ago

@adrienbaron I'm trying to fix it. got passed the paths names, I convert them to posix, since in node require works in posix at windows as well. I can build the project, but generate doesn't work.

After some digging the generate returns error for unix systems as well. I was able to deploy but the logs show errors: TypeError: __webpack_require__(...).__inject__ is not a function From what I could see it loads styles require('vuetify/${style}') what we get is something like require('vuetify/src/components/VGrid/VGrid.sass') and there is no function in a styles file...

so far I was not able to fix it.

adrienbaron commented 4 years ago

@adrienbaron I'm trying to fix it. got passed the paths names, I convert them to posix, since in node require works in posix at windows as well. I can build the project, but generate doesn't work.

After some digging the generate returns error for unix systems as well. I was able to deploy but the logs show errors: TypeError: __webpack_require__(...).__inject__ is not a function From what I could see it loads styles require('vuetify/${style}') what we get is something like require('vuetify/src/components/VGrid/VGrid.sass') and there is no function in a styles file...

so far I was not able to fix it.

Hum, are you sure you followed all the instructions (the manualInject bit)? This __inject__ function is provided by I think Vue loader but you need to pass the right option to it for it to have this behaviour

dor272 commented 4 years ago

@adrienbaron pretty sure, thats my exact config:

  build: {
    extractCSS: true,
    loaders: {
      vueStyle: { manualInject: true }
    }
  }
  vuetify: {
    customVariables: ['~/assets/variables.scss'],
    treeShake: {
      loaderOptions: { registerStylesSSR: true }
    },
    defaultAssets: false,
    theme: {
      dark: false,
      themes: {
        dark: {
          primary: colors.blue.darken2,
          accent: colors.grey.darken3,
          secondary: colors.amber.darken3,
          info: colors.teal.lighten1,
          warning: colors.amber.base,
          error: colors.deepOrange.accent4,
          success: colors.green.accent3
        }
      }
    },
    icon: {
      iconfont: "mdiSvg",
    },
  }
adrienbaron commented 4 years ago

@adrienbaron pretty sure, thats my exact config:

  build: {
    extractCSS: true,
    loaders: {
      vueStyle: { manualInject: true }
    }
  }
  vuetify: {
    customVariables: ['~/assets/variables.scss'],
    treeShake: {
      loaderOptions: { registerStylesSSR: true }
    },
    defaultAssets: false,
    theme: {
      dark: false,
      themes: {
        dark: {
          primary: colors.blue.darken2,
          accent: colors.grey.darken3,
          secondary: colors.amber.darken3,
          info: colors.teal.lighten1,
          warning: colors.amber.base,
          error: colors.deepOrange.accent4,
          success: colors.green.accent3
        }
      }
    },
    icon: {
      iconfont: "mdiSvg",
    },
  }

@dor272 Sorry if this is the case, just to make sure I'll put all my config:

I'm depending on @nuxtjs/vuetify version ^2.0.0-beta.2 and vuetify ^2.3.8.

Then in Nuxt config:

{
  // ...
  buildModules: ["@nuxtjs/vuetify"],
  vuetify: {
    frameworkOptions: {
      theme: {
        disable: true,
        dark: true,
      },
      icons: { iconfont: "mdiSvg" },
    },
    loader: {
      registerStylesSSR: true,
    },
    defaultAssets: false,
    customVariables: ["~/assets/style/vuetify-custom.scss"],
  },
  build: {
    loaders: {
      vueStyle: { manualInject: true },
    },
  }
}

Here is vuetify-custom.scss (shouldn't impact things, just in case you are curious):

// If you need to extend Vuetify SASS lists
@import "~vuetify/src/styles/styles.sass";
$color-pack: false;
$material-dark: map-merge(
  $material-dark,
  (
    cards: #222222, // Grey 2
    bg-color: #101010  // Grey 0
  )
);

// Tabs
$tab-font-size: 0.75rem;
$tabs-item-padding: 0 8px;
$slide-group-prev-basis: 36px;

// Container
$grid-gutter: $spacer * 4;
$container-padding-x: $grid-gutter / 2;

$grid-gutters: map-deep-merge(
  (
    "xs": $grid-gutter / 12,
    "sm": $grid-gutter / 6,
    "md": $grid-gutter / 3,
    "lg": $grid-gutter * 2/3,
    "xl": $grid-gutter
  ),
  $grid-gutters
);

$alert-padding: $spacer * 2;
$alert-margin: $spacer * 2;

$dialog-margin: 8px;

I don't have the extractCSS option set, maybe that's what's breaking things for you?

dor272 commented 4 years ago

@adrienbaron pretty sure, thats my exact config:

  build: {
    extractCSS: true,
    loaders: {
      vueStyle: { manualInject: true }
    }
  }
  vuetify: {
    customVariables: ['~/assets/variables.scss'],
    treeShake: {
      loaderOptions: { registerStylesSSR: true }
    },
    defaultAssets: false,
    theme: {
      dark: false,
      themes: {
        dark: {
          primary: colors.blue.darken2,
          accent: colors.grey.darken3,
          secondary: colors.amber.darken3,
          info: colors.teal.lighten1,
          warning: colors.amber.base,
          error: colors.deepOrange.accent4,
          success: colors.green.accent3
        }
      }
    },
    icon: {
      iconfont: "mdiSvg",
    },
  }

@dor272 Sorry if this is the case, just to make sure I'll put all my config:

I'm depending on @nuxtjs/vuetify version ^2.0.0-beta.2 and vuetify ^2.3.8.

Then in Nuxt config:

{
  // ...
  buildModules: ["@nuxtjs/vuetify"],
  vuetify: {
    frameworkOptions: {
      theme: {
        disable: true,
        dark: true,
      },
      icons: { iconfont: "mdiSvg" },
    },
    loader: {
      registerStylesSSR: true,
    },
    defaultAssets: false,
    customVariables: ["~/assets/style/vuetify-custom.scss"],
  },
  build: {
    loaders: {
      vueStyle: { manualInject: true },
    },
  }
}

Here is vuetify-custom.scss (shouldn't impact things, just in case you are curious):

// If you need to extend Vuetify SASS lists
@import "~vuetify/src/styles/styles.sass";
$color-pack: false;
$material-dark: map-merge(
  $material-dark,
  (
    cards: #222222, // Grey 2
    bg-color: #101010  // Grey 0
  )
);

// Tabs
$tab-font-size: 0.75rem;
$tabs-item-padding: 0 8px;
$slide-group-prev-basis: 36px;

// Container
$grid-gutter: $spacer * 4;
$container-padding-x: $grid-gutter / 2;

$grid-gutters: map-deep-merge(
  (
    "xs": $grid-gutter / 12,
    "sm": $grid-gutter / 6,
    "md": $grid-gutter / 3,
    "lg": $grid-gutter * 2/3,
    "xl": $grid-gutter
  ),
  $grid-gutters
);

$alert-padding: $spacer * 2;
$alert-margin: $spacer * 2;

$dialog-margin: 8px;

I don't have the extractCSS option set, maybe that's what's breaking things for you?

@adrienbaron I upgraded @nuxtjs/vuetify to 2.0.0-beta.2. now nuxt generate doesn't return any error both with extractCSS or without, but I'm still having issues. I checked the /dist folder and it seems most html has the injected style, but I couldn't see it inside index.html. and the content still flashes (at the index or any other route).

I tried to create a new project. fresh install of nuxt and vuetify, upgraded @nuxt/vuetify to the version above and changed it to use vuetify-loader from your repo. when I build it without extractCSS my app.js is 528KB (all of vuetify css). when I build it with extractCSS then around 340KB shifted from app.js to app.css but it still all loaded. I can't understand what am I doing wrong but I can't get rid of all the excessive CSS. That's effecting loading times and performance. I'm sharing here the basic nuxt-vuetify test I did today.

  1. without extractCSS: files: https://github.com/dor272/nuxt-vuetify deployment: https://nuxt-vuetify.vercel.app/

  2. with extractCSS: files: https://github.com/dor272/nuxt-vuetify/tree/extractCSS deployment: https://nuxt-vuetify-dltafcz5v.vercel.app/

you can run lighthouse on both and see performance is pretty poor in mobile and both loading all vuetify css (either from css file or js)

dor272 commented 4 years ago

@adrienbaron so I had a mistake, I didn't see that I need to change vuetify settings when using @nuxtjs/vuetify beta. I changed it but it behaves the same as above. with extractCSS the build return errors, but the generated files look ok. without extractCSS build goes smooth but the content of the site flashes (css is not loaded)

any ideas?

cprcrack commented 3 years ago

@adrienbaron could you clarify what is the best way of making use of your fix currently?

I'm using @nuxtjs/vuetify v1.11.3 which is the latest stable release, and still suffering this issue. I understand that your PR is already merged and released in vuetify-loader v1.7.0 right?

Looking at my node_modules/vuetify-loader/package.json, I'm using v1.7.2 which should thus include your PR, is there any other configuration that needs to be done for SSR to work properly?

Update: I think I needed to do this manual setup:

// nuxt.config.js
export default {
  // ...
  build: {
    loaders: {
      vueStyle: { manualInject: true }
    }
  },
  vuetify: {
    loader: {
      registerStylesSSR: true
    }
  },
  css: [
    // Don't use this, it won't work if manualInject is true
  ],
}

After doing that, there is a noticeable change on the styles rendered server-side, but they are still not right and cause a flash of wrongly styled content before the client is hydrated. Is there anything else I should try?

adrienbaron commented 3 years ago

@cprcrack Your config looks on the right track 👍 ! I haven't updated my loader yet still using my fork but it should work ^^".

One thing to be aware is that if you had files in the css field you need to import them in your default.vue layout, for example:

<style lang="stylus">
@import "../assets/style/app.styl"
</style>

Other than that your config looks OK, I also disabled theme, I don't remember if that had an impact on SSR though (sorry it has been a while):

  vuetify: {
    frameworkOptions: {
      theme: {
        disable: true,
        dark: true,
      },
      icons: { iconfont: "mdiSvg" },
    },
    loader: {
      registerStylesSSR: true,
    },
    defaultAssets: false,
    customVariables: ["~/assets/style/vuetify-custom.scss"],
  },
  build: {
    loaders: {
      vueStyle: { manualInject: true },
    },
  }
cprcrack commented 3 years ago

I finally was able to fix the issue just by enabling the extractCSS option:

// nuxt.config.js
build: {
  extractCSS: true
}

Moreover by enabling extractCSS the total size of the /.nuxt/dist/client/ folder actually decreased from around 820 KB to around 800 KB, so I'm not sure if the whole Vuetify CSS is being included, but if it was, it was being included already before enabling extractCSS.

Regarding why it fixed it, maybe it had something to do with unscoped styles that I was using in my .vue files. Update: not really, doesn't seem to make a difference.

larzon83 commented 3 years ago

I toyed around with this and to get it working with current nuxt/vuetify-module v1.11.3 to config should be like this:

// nuxt.config.js
export default {
  // ...
  build: {
    loaders: {
      vueStyle: { manualInject: true }
    }
  },
  vuetify: {
    treeShake: {
      loaderOptions: {
        registerStylesSSR: true
      }
    }
  },
  css: [
    // Don't use this, it won't work if manualInject is true
  ],
}

I feel that Lighthouse scores are slightly better with this instead

build: {
  extractCSS: true
}

You get some small penalties for "remove unused css", but overall score is still better.

thnee commented 3 years ago

This really needs a proper fix. When using the regular v-bottom-navigation component with v-btn with treeShake: true in Nuxt SSR mode, it breaks. The margins are all wrong and the buttons look broken. Disabling treeShake makes everything look fine.

I have tried all various combinations of settings in this issue and nothing solves the issue. When using the following config:

  build: {
    extractCSS: true,
    loaders: {
      vueStyle: {
        manualInject: true,
      },
    },
  },

  vuetify: {
    customVariables: ["~/assets/styles/variables.scss"],
    optionsPath: "./vuetify.options.js",

    treeShake: {
      loaderOptions: {
        registerStylesSSR: true,
      },
    },
  },

It produces error:

ERROR  [Vue warn]: Error in beforeCreate hook: "TypeError: __webpack_require__(...).__inject__ is not a function"

found in

---> <Layouts/default.vue> at layouts/default.vue
       <Root>
RobbieTheWagner commented 3 years ago

I'm seeing the same webpack error.