blokwise / dynamic

Load components initialized through @nuxt/components dyamically.
https://dynamic.blokwise.io
MIT License
56 stars 8 forks source link

Can't use in nuxt3 #15

Open shtse8 opened 2 years ago

shtse8 commented 2 years ago
[Vue warn]: Property "$nuxtDynamic" was accessed during render but is not defined on instance.
aerophobic commented 2 years ago

@shtse8 sorry for the late response here. the current version is compatible with nuxt v2 - a version compatible with nuxt v3 is in the works. I'll keep this issue open and notify you when it'll be ready.

liamb13 commented 2 years ago

How’s this coming along @aerophobic? Do you need any support?

aerophobic commented 2 years ago

@liamb13 I'm indeed struggling to find a proper way to solve this in nuxt v3. Grabbing the components in the module to read (or generate) dynamic import paths is doable. But I can't get my head around on how to pass them to a plugin (or inject them in any other way to the context) to make use of them in the NuxtDynamic component.

Any ideas are welcome :)

aerophobic commented 2 years ago

@liamb13 & @shtse8: I found a way to do it. Had to rewrite the hydration part myself instead of using vue-lazy-hydration but I got a working prototype now. I'll test some more, clean everything up and provide a preversion for you guys.

How you'd like the idea handling hydration as following instead of passing a string for the hydration type:

<!-- for default hydration (instant) -->
<NuxtDynamic component="FieldText" name="firstname" />

<!-- hydrating when idle -->
<NuxtDynamic component="FieldText" name="firstname" when-idle />

<!-- hydrating when visible -->
<NuxtDynamic component="FieldText" name="firstname" when-visible />

<!-- hydrating never -->
<NuxtDynamic component="FieldText" name="firstname" never />

<!-- hydrating on event -->
<NuxtDynamic component="FieldText" name="firstname" on="mouseover" />
liamb13 commented 2 years ago

@aerophobic this looks a lot cleaner in my opinion. Only thought; is there a use case where hydration would need to be computed/changed?

mbeckershc commented 2 years ago

I would be keen to try the pre-version also :)

aerophobic commented 2 years ago

@liamb13 thought about that too. how about having props aswell concrete as dynamic so you can choose which way you want to configure the component:

<!-- for default hydration (instant) -->
<NuxtDynamic component="FieldText" name="firstname" />

<!-- hydrating when idle -->
<NuxtDynamic component="FieldText" name="firstname" when-idle />

<!-- hydrating when visible -->
<NuxtDynamic component="FieldText" name="firstname" when-visible />

<!-- hydrating never -->
<NuxtDynamic component="FieldText" name="firstname" never />

<!-- hydrating on event -->
<NuxtDynamic component="FieldText" name="firstname" on="mouseover" />

<!-- dynamically configure the component -->
<NuxtDynamic component="FieldText" name="firstname" :hydration="{ type: 'on', options: 'mouseover' }" />

WDYT?

liamb13 commented 2 years ago

@aerophobic the best of both worlds. I think that's perfect. Super clean for 90% of cases, while giving the ability to deep dive if required.

liamb13 commented 2 years ago

I'll test this out toward the end of the week and share my thoughts. Great work @aerophobic!

aerophobic commented 2 years ago

@liamb13 @mbeckershc @shtse8 a preversion is ready to be tested with nuxt v3:

yarn add @blokwise/dynamic@next

the docs are not updated yet, neither are the tests. the component can be used as described in the comment above. for a deeper understanding on how to use props see comments in the sourcecode of the component or its composables.

let me know if you experience any issues 🙏

mbeckershc commented 2 years ago

Hi @aerophobic ,

Thank you for all your hard work!

I seem to have it mostly sorted, however I'm getting the following error.

[Vue warn]: Unhandled error during execution of setup function 
  at <Dynamic key=0 isComponent="BasicTextContent" name="basic-text-content"  ... >
[nitro] [dev] [unhandledRejection] ReferenceError: ref is not defined

My current code is:

<NuxtDynamic
        v-for="(component, i) in page.attributes.Page_Body"
        :key="i"
        :isComponent="toPascalCase(component.__component.split('.')[1])"
        :name="component.__component.split('.')[1]"
        :data="component"
        :path="route.params.slug"
        componentRef="cmpRef"
        ref="component"
        when-visible
      />

This is happening both with and without the refs being added.

  componentRef="cmpRef"
        ref="component"
mbeckershc commented 2 years ago

Actually, I wonder if it could be from these warnings.

 WARN  Duplicated imports "useDetectTypes", the one from "C:/Users/Matthew/Documents/SHC Group/shc-nuxt-app/node_modules/@blokwise/dynamic/dist/runtime/composables/useDetectTypes.d.ts" has been ignored

 WARN  Duplicated imports "useHydrate", the one from "C:/Users/Matthew/Documents/SHC Group/shc-nuxt-app/node_modules/@blokwise/dynamic/dist/runtime/composables/useHydrate.d.ts" has been ignored

 WARN  Duplicated imports "useSwitchCases", the one from "C:/Users/Matthew/Documents/SHC Group/shc-nuxt-app/node_modules/@blokwise/dynamic/dist/runtime/composables/useSwitchCases.mjs" has been ignored
aerophobic commented 2 years ago

hey @mbeckershc thanks for testing and for your response. I'll try to reproduce your issue and get back at you with feedback. The warnings shouldn't be a problem, but need to be fixed aswell, thanks for pointing that out 🙏

aerophobic commented 2 years ago

@mbeckershc I found and solved the issue regarding the error [nitro] [dev] [unhandledRejection] ReferenceError: ref is not defined in the latest version - testing looked well on my side. you can just reinstall the package with the next tag.

the memtioned warning about duplicated imports still persist but the issue does not impact the functionality.

be aware that the componentRef prop has been removed because nuxt does handle ref binding differently with v3. maybe I come up with a different solution in the future.

as always: if you experience problems, don't hesitate to report them here 🙏

mbeckershc commented 2 years ago

@aerophobic Amazing! Thank you very much, will give it a go today!

Regarding the componentRef for my project at least, refs are not necessary at all. Was just trying them to see if it made any difference with the ref error.

liamb13 commented 2 years ago

Not exactly sure where I'm going wrong. I'm just trying to get a simple example setup and can't seem to receive any errors nor components.

I'm calling:

<script lang="ts" setup>
defineProps({ blok: Object })
const socialMedia = [
  {
    url: 'https://facebook.com',
    platform: 'facebook',
  },
]
const content = 'testing string'
</script>

<template>
  <div v-editable="blok">
    <p v-for="(item, index) in blok.show" :key="index">
      {{ item }}
    </p>
    <NuxtDynamic
      v-for="(item, i) in blok.show"
      :key="i"
      :component="item"
      :name="item"
      :data="{ socialMedia, content }"
    />
  </div>
</template>

blok.show = [ "DynamicSocial", "DynamicString" ]

Using this works as expected:

<DynamicSocial :data="{ socialMedia, content }" />
<DynamicString :data="{ socialMedia, content }" />

NuxtDynamic doesn't show anything. No errors, no content.

aerophobic commented 2 years ago

@liamb13 I just released a new version fixing an issue which ended up not loading and displaying the fallback component if a component could not be loaded.

with version v2.0.0-4 you should see messages when components could not be loaded with your code.

I could not reproduce it so far, but:

if you'd provide a reproduction link I could look into your issue.

btw: I see you are loading dynamic components upon storyblok data, am I right? I'll release a new version of @blokwise/blok which is actually a nuxt module providing a component which makes use of the NuxtDynamic component to load components of storyblok schemas recoursively (for nested bloks). the new version compatible with nuxt v3 is in the works and can be released soon. if you are interested, I'll hit you up when it's ready :)

liamb13 commented 2 years ago

@aerophobic I'll share a reproduction link shortly. I am trying with Storyblok so please keep me posted on that update.

I'm strongly considering reverting to a Nuxt 2/Storyblok setup for that project. Just too many little gotchas popping up for the time being.

aerophobic commented 2 years ago

sorry for the inconvenience - but I can fully understand that deicision. I didn't migrate projects or started new ones with nuxt v3 neither - at least not for production. there are struggles to overcome, still. the latest RC is quite promising, but lack of docs at some points make it hard to implement seamlessly.

I'll keep you posted about the @blokwise/blok module

aerophobic commented 2 years ago

@liamb13 I kinda found the issue causing problems in your code: if you remove the v-editable directive you should see your components getting loaded (even with name and component prop).

did you set up the @storyblok/nuxt module the correct way?

liamb13 commented 2 years ago

Thank you @aerophobic! No apology needed either.

It's possible I haven't. I just followed the Storyblok tutorial and haven't delved much further.

matthewbecker1990 commented 2 years ago

@liamb13 Have you had any luck getting this working?

gregg-cbs commented 1 year ago

Would also love to use this. I assumed the current Nuxt 3 auto import of components would work with headless cms vibes but it doesnt.

JackEdwardLyons commented 1 year ago

I've also noticed the useDetectTypes error:

vue-router.mjs:3451 SyntaxError: The requested module '/_nuxt/node_modules/@blokwise/dynamic/dist/runtime/composables/useDetectTypes.d.ts?v=1dc4d1a3' does not provide an export named 'useDetectTypes' (at useHydrate.mjs?v=1dc4d1a3:2:10)`

Currently using the latest "@blokwise/dynamic": "^2.0.0-6",

Any idea on how this can be fixed?

renardsas commented 1 year ago

I've also noticed the useDetectTypes error:

vue-router.mjs:3451 SyntaxError: The requested module '/_nuxt/node_modules/@blokwise/dynamic/dist/runtime/composables/useDetectTypes.d.ts?v=1dc4d1a3' does not provide an export named 'useDetectTypes' (at useHydrate.mjs?v=1dc4d1a3:2:10)`

Currently using the latest "@blokwise/dynamic": "^2.0.0-6",

Any idea on how this can be fixed?

Same error : "@blokwise/dynamic": "^2.0.0-6" Nuxt : v3.0.0-RC.12

rlaven commented 1 year ago

@aerophobic Any updates regarding the move to nuxt3?

Thanks in advance!

aerophobic commented 1 year ago

Hey folks. Hadn't the chance to finalize this for nuxt v3 due to missing time and focus. I'll look into this in the coming week and try to come up with a solution. If someone would like to assist in any way, feel free to ping me.

I keep you updated in this thread about the state of the project and its compatibility for nuxt v3.

gregg-cbs commented 1 year ago

I used vue 3 on a headless cms for a module based front end.

This is the main part of the code I used to have dynamically loaded components in the browser, might be helpful to you or others:

<template>
  <div v-if="components">
    <component 
      v-for="(component, index) in components" 
      :key="index"
      :is="component.component"
      v-bind="component.data"
    />
  </div>
</template>

<script>
import { defineAsyncComponent } from 'vue';

export default {
  data:()=> ({
    components: null, // [{data_props, component_name}]
  }),
  async created() {
    // components (i had an array of components to load)
    const components = [
      {
        name: "ModuleAccordion",
        data: {theme: 'blue', title: "hello", body: "I am here"}
      },
      {
        name: "ModuleBanner",
        data: {title: "hello", body: "I am here", img: "https://placeholder.com/assets/images/150x150-500x500.png"}
      }
    ]

    // import components
    if (components) {
      const dynamic_components = components.map((component)=> {
        const {name, data} = component;

        // split the data and the component instance so you can v-bind the data easier in the template
        return {
          data: data,
          component: defineAsyncComponent(() => import(`./components/Module/${name}.vue`))
        }
      })

      // download all components over the network before rendering the page
      // otherwise the page jumps around as components load in
      await Promise.all(dynamic_components.map((component)=> {
        return component.component.__asyncLoader()
      }))

      // we do not want components to be reactive data, this can cause performance issues, so we freeze the object
      // vue understands frozen objects should not be reactive.
      this.components = Object.freeze(dynamic_components)
    }
  }
}
</script>
muellercornelius commented 1 year ago

Hi Guys ;)

matias-gmg commented 1 year ago

Hi everyone!

Just wanted to know what is the status of this update.

I am currently migrating a website from Nuxt 2 to Nuxt 3 and I have this package as a dependency. I have added @blokwise/dynamic@2.0.0-6 to my project and now I am getting the following warnings:

WARN  Duplicated imports "useDetectTypes", the one from "/node_modules/@blokwise/dynamic/dist/runtime/composables/useDetectTypes.d.ts" has been ignored

WARN  Duplicated imports "useHydrate", the one from "/node_modules/@blokwise/dynamic/dist/runtime/composables/useHydrate.d.ts" has been ignored

WARN  Duplicated imports "useSwitchCases", the one from "/node_modules/@blokwise/dynamic/dist/runtime/composables/useSwitchCases.d.ts" has been ignored

WARN  Duplicated imports "useDetectTypes", the one from "/node_modules/@blokwise/dynamic/dist/runtime/composables/useDetectTypes.d.ts" has been ignored

WARN  Duplicated imports "useHydrate", the one from "/node_modules/@blokwise/dynamic/dist/runtime/composables/useHydrate.d.ts" has been ignored

WARN  Duplicated imports "useSwitchCases", the one from "/node_modules/@blokwise/dynamic/dist/runtime/composables/useSwitchCases.d.ts" has been ignored

Is this production ready or do we have to wait for a new release? Thank you!

aerophobic commented 1 year ago

Hey folks! It has been quite some time since the last update. So here it is:

With the stable releases of Nuxt 3 moving forward and the additions of new tools via @nuxt/kit for module authors, I decided to rewrite the approach how the components will be detected, asynchronously loaded or lazily hydrated.

I got a working PoC, which works flawlessly on my end. I'm going to refactor a couple of things and push a new preversion within the next week for everyone interested in testing and playing around with it.

The module will be capable of detecting, auto-importing, registering and rendering components without the limitation of pointing to a specific subdirectory as in the approach @gregg-cbs suggested.

Stay tuned 👾

donPuerto commented 1 year ago

I just have error, after installation and setting up in nuxt config

ERROR  Cannot restart nuxt:  Cannot read properties of undefined (reading 'nuxt')                                                                            4:48:12 AM  

  at dynamicModule (D:/Code/Nuxt/v3/nuxt3-primevue3-crm-v1/node_modules/@blokwise/dynamic/src/module.js:8:8)
  at installModule (/D:/Code/Nuxt/v3/nuxt3-primevue3-crm-v1/node_modules/nuxt/node_modules/@nuxt/kit/dist/index.mjs:2409:101)
  at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
  at async initNuxt (/D:/Code/Nuxt/v3/nuxt3-primevue3-crm-v1/node_modules/nuxt/dist/index.mjs:3231:7)
  at async load (/D:/Code/Nuxt/v3/nuxt3-primevue3-crm-v1/node_modules/nuxi/dist/chunks/dev.mjs:205:9)
  at async _applyPromised (/D:/Code/Nuxt/v3/nuxt3-primevue3-crm-v1/node_modules/nuxi/dist/chunks/dev.mjs:97:10)
physics515 commented 1 year ago

@aerophobic I am getting this error when using the @next version:

Internal server error: Failed to resolve import "#components" from "node_modules\@blokwise\dynamic\dist\runtime\components\dynamic\Dynamic.vue". Does the file exist?                                                                                                                                                                                    
                   1:39:43 PM
  Plugin: vite:import-analysis
  File: ******/node_modules/@blokwise/dynamic/dist/runtime/components/dynamic/Dynamic.vue:114:14
  105|    ([{ never, whenIdle, whenVisible, on }]) => {
  106|      LazyComponent.value = hydrate(() =>
  107|        import('#components').then((c) => {
     |               ^
  108|          if (c.componentNames.includes(componentName.value)) {
  109|            return c[componentName.value]

Any idea what is going on here? Here is my code:

<script setup>
    const dynamic_comp = 'Card';
</script>

<template>
    <NuxtDynamic :component="dynamic_comp"></NuxtDynamic>
</template>

Edit: I noticed that I am also getting these error & warnings on dev server startup:

 WARN  Duplicated imports "useDetectTypes", the one from "C:/Users/physi/Desktop/Pricing Tools/pricing_tool_2/node_modules/@blokwise/dynamic/dist/runtime/composables/useDetectTypes.d.ts" has been ignored                                                                                                                                          1:53:11 PM

 WARN  Duplicated imports "useHydrate", the one from "C:/Users/physi/Desktop/Pricing Tools/pricing_tool_2/node_modules/@blokwise/dynamic/dist/runtime/composables/useHydrate.d.ts" has been ignored                                                                                                                                                  1:53:11 PM  

 WARN  Duplicated imports "useSwitchCases", the one from "C:/Users/physi/Desktop/Pricing Tools/pricing_tool_2/node_modules/@blokwise/dynamic/dist/runtime/composables/useSwitchCases.d.ts" has been ignored                                                                                                                                          1:53:11 PM  

 WARN  Duplicated imports "useDetectTypes", the one from "C:/Users/physi/Desktop/Pricing Tools/pricing_tool_2/node_modules/@blokwise/dynamic/dist/runtime/composables/useDetectTypes.d.ts" has been ignored                                                                                                                                          1:53:19 PM  

1:53:59 PM
 ERROR  Internal server error: Failed to resolve import "#components" from "node_modules\@blokwise\dynamic\dist\runtime\components\dynamic\Dynamic.vue". Does the file exist?
matias-gmg commented 1 year ago

I am getting exactly the same error and warnings.

@aerophobic: is the new release you mentioned ready?

Thanks!

martijndewit commented 1 year ago

[nuxt] Could not resolve id #components

Can this be related to : https://github.com/nuxt/nuxt/issues/22833 🤷‍♂️

Bartas139 commented 5 months ago

@aerophobic Hi, is there any progress on Nuxt3 version?

I am getting this error:

 ERROR  (node:11904) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.                                                                               10:02:09  
(Use node --trace-warnings ... to show where the warning was created)

 ERROR  Cannot start nuxt:  Cannot read properties of undefined (reading 'nuxt')                                                                                                                      10:02:09  

  at dynamicModule (C:/Dev/CMS/node_modules/@blokwise/dynamic/src/module.js:8:8)
  at installModule (/C:/Dev/CMS/frontend/node_modules/@nuxt/kit/dist/index.mjs:2415:101)
  at async initNuxt (/C:/Dev/CMS/frontend/node_modules/nuxt/dist/index.mjs:4171:7)
  at async NuxtDevServer._load (/C:/Dev/CMS/frontend/node_modules/nuxi/dist/chunks/dev2.mjs:6879:5)
  at async NuxtDevServer.load (/C:/Dev/CMS/frontend/node_modules/nuxi/dist/chunks/dev2.mjs:6811:7)
  at async NuxtDevServer.init (/C:/Dev/CMS/frontend/node_modules/nuxi/dist/chunks/dev2.mjs:6806:5)
  at async Object.run (/C:/Dev/CMS/frontend/node_modules/nuxi/dist/chunks/dev-child.mjs:99:5)
  at async runCommand$1 (/C:/Dev/CMS/frontend/node_modules/nuxi/dist/shared/nuxi.9edf0930.mjs:1648:16)
  at async runCommand$1 (/C:/Dev/CMS/frontend/node_modules/nuxi/dist/shared/nuxi.9edf0930.mjs:1639:11)
  at async runMain$1 (/C:/Dev/CMS/frontend/node_modules/nuxi/dist/shared/nuxi.9edf0930.mjs:1777:7)

Update: Sorry, I just discovered new prerelease versions for Nuxt3, but it still doesnt work for me. I tried the latest one v2.0.0-6 and I get this error:

[plugin:vite:import-analysis] Failed to resolve import "#components" from "node_modules/@blokwise/dynamic/dist/runtime/components/dynamic/Dynamic.vue". Does the file exist?
C:/Dev/CMS/frontend/node_modules/@blokwise/dynamic/dist/runtime/components/dynamic/Dynamic.vue:114:14
103|    ([{ never, whenIdle, whenVisible, on }]) => {
104|      LazyComponent.value = hydrate(() =>
105|        import('#components').then((c) => {
   |               ^
106|          if (c.componentNames.includes(componentName.value)) {
107|            return c[componentName.value]

Thanks