vuetifyjs / nuxt-module

Zero-config Nuxt Module for Vuetify
https://nuxt.vuetifyjs.com/
MIT License
223 stars 22 forks source link

Unable to run with storybook #179

Open AndreyYolkin opened 10 months ago

AndreyYolkin commented 10 months ago

My setup:

Reproduction

https://github.com/AndreyYolkin/storybook-vuetify-issue

Description

Thank you for your titanic work on building this module. I've tried to add storybook into my project, but for some reasons vuetify works in dev mode and have some problems inside storybook. Please follow the readme to get the error in reproduction.

Additional details

  1. There is a working example with another nuxt-vuetify module (not maintained anymore): https://github.com/storybook-vue/storybook-nuxt-starter
  2. I've also left the comment in storybook-nuxt repo https://github.com/storybook-vue/storybook-nuxt/issues/42#issuecomment-1877067150
userquin commented 10 months ago

Vuetify components seems to be loaded without defaults, I'm checking if there is a problem with vuetify post plugin in this module and storybook.

FYI: I don't see any page using any Vuetify component in https://github.com/storybook-vue/storybook-nuxt-starter

userquin commented 10 months ago

I don't know why applyNuxtPlugins are called after rendering the pages, I just added a breakpoint in the nuxtjs/i18n warning, storybook should review Nuxt 3 integration logic.

This module enables treeshaking feature via vuetify vite plugin (there is no way to use all components, you need to add them to vuetify.vuetifyOptions.components in the nuxt configuration or vuetify config file), the deprecated nuxt module by default not enabling that feature IIRC (maybe also a problem with nuxt vuetify sequential post plugin, i18n is installed and configured in the app).

AndreyYolkin commented 10 months ago

FYI: I don't see any page using any Vuetify component in https://github.com/storybook-vue/storybook-nuxt-starter

Of course, here is the direct link to component: https://github.com/storybook-vue/storybook-nuxt-starter/blob/master/components/vuetify/index.vue

And Story: https://github.com/storybook-vue/storybook-nuxt-starter/blob/master/stories/Vuetify.stories.ts

Only these files, pages folder looks like boilerplate

userquin commented 10 months ago

If you run the dev server, you can see vuetify components imports at the bottom:

imagen

Same component in storebook (missing imports):

imagen

userquin commented 10 months ago

The i18n module seems to be fine, so the problem should be in storebook: it seems it is building the project but I have no idea what's doing behind the scenes: the vuetify vite plugin is registered manually by this module and injects the vuetify imports parsing the vue file in the vite plugins pipeline.

EDIT: you cannot register the vuetify vite plugin in your nuxt config file, this module will throw an error if it is found.

AndreyYolkin commented 10 months ago

Reproduction repo also has story, where I defined imports manually, but in that case I get Could not find defaults instance issue. I suppose it also happens because nuxt plugin runs too late

image
userquin commented 10 months ago

This module enables treeshaking feature via vuetify vite plugin (there is no way to use all components, you need to add them to vuetify.vuetifyOptions.components in the nuxt configuration or vuetify config file), the deprecated nuxt module by default not enabling that feature IIRC (maybe also a problem with nuxt vuetify sequential post plugin, i18n is installed and configured in the app).

It is about global components: check this entry https://vuetifyjs.com/en/features/treeshaking/

userquin commented 10 months ago

I suppose it also happens because nuxt plugin runs too late

No, it seems vuetify vite plugin missing from vite plugins.

AndreyYolkin commented 10 months ago

Ok, thank you for your answers, I'll move on with investigation in storybook ❤️

userquin commented 10 months ago

This plugin should add the imports (a copy/paste from the original): https://github.com/userquin/vuetify-nuxt-module/blob/main/src/vite/vuetify-import-plugin.ts#L25-L49

I'm going to check if being called when running nr storebook, and check what's running storebook, the dev server or the build.

First time I use storybook ;)

AndreyYolkin commented 10 months ago

Me too, honestly. Part of big Nuxt2/3 migration

Edit: They have viteFinal option for .storybook/main.ts: https://storybook.js.org/docs/configure, which returns full vite config

userquin commented 10 months ago

Using pnpm dev:

imagen

userquin commented 10 months ago

Running pnpm storybook (missing trace):

imagen

userquin commented 10 months ago

Anyway, there is no entry for Nuxt 3 in the docs, with nuxt modules you can do a lot of things, you have layers, you have module hooks (communication between modules), storybook cannot use only vite, Nuxt 3 is built on top of Nitro and Vite

userquin commented 10 months ago

It seems we need to patch or use another plugin, the plugin being called but storybook maybe adding some vite plugin to transform vue files.

AndreyYolkin commented 10 months ago

I think I will dive into storybook-nuxt internals, like https://github.com/storybook-vue/storybook-nuxt/blob/main/packages/storybook-nuxt/src/runtime/plugins/storybook.ts or https://github.com/storybook-vue/storybook-nuxt/blob/main/packages/storybook-nuxt/src/preset.ts

userquin commented 10 months ago

it is being called in the build, it works, the imports are there, but storybook calling again with raw vue file:

imagen

userquin commented 10 months ago

In build:

imagen

userquin commented 10 months ago

imagen

userquin commented 10 months ago

why building to request raw file?

userquin commented 10 months ago

ok, found the problem: https://github.com/storybook-vue/storybook-nuxt/blob/main/packages/storybook-nuxt/src/preset.ts#L95C26-L97

calling with raw vue file since it is moving all plugins before vue

AndreyYolkin commented 10 months ago

Oh, I was near, but moved into main storybook repo.

We can modify vite config back by using viteFinal inside .storybook/main.ts and move all vuetify plugins after vue plugin

import type { StorybookConfig } from "@storybook-vue/nuxt";
import {ViteConfig} from "@nuxt/schema";

const config: StorybookConfig = {
  stories: [
    "../stories/**/*.mdx",
    "../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)",
  ],
  addons: [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-interactions",
  ],
  framework: {
    name: "@storybook-vue/nuxt",
    options: {},
  },
  docs: {
    autodocs: "tag",
  },
  viteFinal: (config: ViteConfig) => {
    console.log(config.plugins?.map(p => p.name));
    return config
  }
};
export default config;
userquin commented 10 months ago

No, it is better to use an object notation for the transform hook using enforce/order 'post': I'm testing in my local...

EDIT: cannot use object notation (it is not transformIndexHtml), adding enforce: 'post', doesn't work, now we have the same error in any history

userquin commented 10 months ago

imagen

AndreyYolkin commented 10 months ago

I've achieved the same result rn with this: image

userquin commented 10 months ago

adding enforce: 'post':

imagen

userquin commented 10 months ago

I'm going to update the repo to ^7.6.7 :fingers_crossed:

userquin commented 10 months ago

no luck:

imagen

AndreyYolkin commented 10 months ago

tried too, unluko

userquin commented 10 months ago

The pages and components being rendered before vuetify is created providing the defaults (createVuetify in vuetify fw module)

AndreyYolkin commented 10 months ago

But AFAIK, all plugins runs before components rendering 🫨

userquin commented 10 months ago

Tried also using defineAsyncComponent, no luck, same error (removing enforce: 'post' patch):

const Vuetify = defineAsyncComponent({
  loader: () => import('~/components/vuetify/index.vue').then(m => m.default ?? m),
  loadingComponent: () => h('div', 'loading...'),
  onError(error, retry, fail, attempts) {
    console.error('Vuetify::error', error)
  },
})
const VuetifyWithImports = defineAsyncComponent({
  loader: () => import('~/components/vuetify/withImports.vue').then(m => m.default ?? m),
  loadingComponent: () => h('div', 'loading...'),
  onError(error, retry, fail, attempts) {
    console.error('VuetifyWithImports::error', error)
  },
})
userquin commented 10 months ago

The example using vuetify in storybook not working, in fact, not working even in dev server with latest vuetify, vite and storybook versions: https://github.com/storybookjs/vue3-code-examples

userquin commented 10 months ago

@AndreyYolkin using the deprecated vuetify module working with latest vuetify, nuxt, vite and storybook versions?

AndreyYolkin commented 10 months ago

Will try tomorrow, not sure, because it was released even before vuetify 3.4 and nuxt 3.7.

Sorry, another timezone

AndreyYolkin commented 10 months ago

Tried with timeout, but still got missing defaults

image
AndreyYolkin commented 10 months ago

Meanwhile, the deprecated module (OTP was introduced in 3.4):

https://github.com/AndreyYolkin/storybook-vuetify-issue/tree/invictus

image
chakAs3 commented 10 months ago

Vuetify components seems to be loaded without defaults, I'm checking if there is a problem with vuetify post plugin in this module and storybook.

FYI: I don't see any page using any Vuetify component in https://github.com/storybook-vue/storybook-nuxt-starter

I have released @storybook-vue/nuxt 0.2.1 with patch fixing this issue,.

if it did not work for you please create a repro repo for me. i will check it out

AndreyYolkin commented 10 months ago

if it did not work for you please create a repro repo for me. i will check it out

Glad you joined us!

I've updated the repo's deps to the latest version, but problem still exists. Please, check the main branch at https://github.com/AndreyYolkin/storybook-vuetify-issue

AndreyYolkin commented 10 months ago

https://github.com/vuetifyjs/vuetify/blob/26c72b3601b12531498cd47297f8565de49496c1/packages/vuetify/src/composables/theme.ts#L306

I've tried to remove manipulation with usehead and keep only old approach and theme is working

Honestly, not surprised, as uncommented code doesn't rely on app

  function install(app) {
    if (parsedOptions.isDisabled) return;
    // const head = app._context.provides.usehead;
    // if (head) {
    //   if (head.push) {
    //     const entry = head.push(getHead);
    //     if (IN_BROWSER) {
    //       watch(styles, () => {
    //         entry.patch(getHead);
    //       });
    //     }
    //   } else {
    //     if (IN_BROWSER) {
    //       head.addHeadObjs(computed(getHead));
    //       watchEffect(() => head.updateDOM());
    //     } else {
    //       head.addHeadObjs(getHead());
    //     }
    //   }
    // } else {
      let styleEl = IN_BROWSER ? document.getElementById('vuetify-theme-stylesheet') : null;
      if (IN_BROWSER) {
        watch(styles, updateStyles, {
          immediate: true
        });
      } else {
        updateStyles();
      }
      function updateStyles() {
        if (typeof document !== 'undefined' && !styleEl) {
          const el = document.createElement('style');
          el.type = 'text/css';
          el.id = 'vuetify-theme-stylesheet';
          if (parsedOptions.cspNonce) el.setAttribute('nonce', parsedOptions.cspNonce);
          styleEl = el;
          document.head.appendChild(styleEl);
        }
        if (styleEl) styleEl.innerHTML = styles.value;
      }
    // }
  }
image
antrax-x5 commented 9 months ago

Hi, @AndreyYolkin , did you found stable working solution for vuetify-nux-module + storybook ??

AndreyYolkin commented 9 months ago

Hi, @AndreyYolkin , did you found stable working solution for vuetify-nux-module + storybook ??

Hi, I ended up with writing own "storybook". I's not so hard, especially if you don't want to automatically get information about slots

fredimitchel commented 8 months ago

It seems we have the same issue with Histoire...

https://github.com/histoire-dev/histoire/issues/701

enzonzee commented 7 months ago

@nuxtjs/storybook v8.0.0 propably fix this issue

fredimitchel commented 7 months ago

Of which library?

enzonzee commented 5 months ago

@nuxtjs/storybook v8.0.0

jgcarrillo commented 4 months ago

I came across with this issue and the problem still persist.

I don't know wether my problem is related with this issue, but I am using Nuxt 3 with Vuetify 3 and Storybook (@nuxtjs/storybook) and I am having the following error:

Failed to build the preview
Error: Vuetify plugin must be loaded after the vue plugin

I think it is because of vite-plugin-vuetify.

Any help would be appreciated 🙌🏻

tobiasdiez commented 4 months ago

I tried to work on this at https://github.com/nuxt-modules/storybook/pull/614 but got stuck (see PR description there). Would appreciate if someone could take over from here, as I'm not using vuetify myself.