histoire icon indicating copy to clipboard operation
histoire copied to clipboard

histoire-plugin-nuxt: provide from plugin not working with useNuxtApp in component

Open CIB opened this issue 1 year ago • 4 comments

Describe the bug

When using provide from a nuxt plugin, and inserting the provided value into a component using useNuxtApp, the provided value will not be available, and an error will be thrown.

Reproduction

Stackblitz: https://stackblitz.com/edit/nuxt-starter-7avtmp?file=components%2Ftest.vue

In plugins/example.ts:

  return {
    provide: {
      example: { foo: 'bar' },
    },
  };

In components/test.vue

const nuxtApp = useNuxtApp();
const foo = nuxtApp.$example.foo;

Then try to start histoire dev with a story that includes <Test />, and an error will be thrown that nuxtApp.$example is undefined.

System Info

System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 18.18.0 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.2.3 - /usr/local/bin/npm
    pnpm: 8.14.0 - /usr/local/bin/pnpm
  npmPackages:
    @histoire/plugin-nuxt: ^0.17.8 => 0.17.8 
    @histoire/plugin-vue: ^0.17.8 => 0.17.8 
    histoire: ^0.17.8 => 0.17.8

Used Package Manager

npm

Validations

CIB avatar Jan 22 '24 15:01 CIB

Same issue when using nuxtApp.provide('helpers', helpers); (which I guess has the same logic under the hood.

dreitzner avatar Jan 30 '24 09:01 dreitzner

This is because Histoire/plugin-next stub out useNuxtApp?

positiveprogrammer avatar Jan 30 '24 09:01 positiveprogrammer

This is because Histoire/plugin-next stub out useNuxtApp?

That's the problem.

The stub could replicate a simple provide by doing something like this:

const nuxtApp = {
    runWithContext: async fn => await fn(),
    provide(key, value) {
        const propertyName = '$' + key;
        nuxtApp[propertyName] = value;
    }
}

export const useNuxtApp = () => nuxtApp

However, this doesn't completely solve the issue, because I'm seeing that plugins don't get access to the stubbed nuxtApp. So anything they provide still won't be available to components in histoire.

export default defineNuxtPlugin(async (nuxtApp) => {
  // nuxtApp here is not the stubbed one
})
export default defineNuxtPlugin(() => {
  return {
    // This is not going to interact with the stubbed nuxtApp
    provide: {
      img: useImage(),
    },
  }
})

I don't fully understand the context around why the decision was made to stub nuxtApp.

If I disable it (by removing the imports:sources hook) here: https://github.com/histoire-dev/histoire/blob/main/packages/histoire-plugin-nuxt/src/index.ts#L147, histoire is able render all of my components as expected without any noticeable issue.

@Akryum, @danielroe, or others. Some additional high-level info may help someone address the issue.

Related: https://github.com/histoire-dev/histoire/pull/710

0x100101 avatar Jun 12 '24 19:06 0x100101