components: Components are not found when using is-Directive
Describe the bug
I expected components to be available for use via is, like this:
<component is="ComponentName">
But from the error log it seems that the components are not registered.
To Reproduce Check the console output at https://codesandbox.io/s/nuxt-components-fdcw5?file=/components/LazyComponentA.vue
Expected behavior Components should render the same as if using them directly.
Additional context Add any other context about the problem here.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 14
- Comments: 31 (2 by maintainers)
Hi @hv-pul ,
<component>is intended to only be used withisvalue being a dynamic variable. And the variable being dynamic, Nuxt.js can’t determine which components to import.We’ve been thinking of a possible implementation with automatic performance boost by lazy loading the components wanted this way :
What do you think ?
Hi. Sorry this issue left unanswered. Actually by
globaloption it is possible to use dynamic components.(sandbox)
Please note that
globaloption does not means components are added to main chunk but they are dynamically imported with webpack (see here and here)This option is disabled by default purposefully because forcing webpack to make one async chunk per-component makes chunking less efficient (this is same technique used by @aerophobic module) so you have to only use for dirs/when dynamic components are necessary
Ok. I just wanted to confirm, that the dynamic components import works already even without specifying
global: true. I tested on my Storyblok project, where I am getting the name/type of the component from API and the<component :is="variable"/>approach worked.Hi @kevinmarrec,
thanks a lot for your explanation. I mistakenly thought that all components would be imported gloablly, but I see you parse the markup instead.
I have to say I’m not a big fan of the magic comment annotation. It does not seem very Vue-idiomatic to me. It would In that case I guess you could just as well use explicit imports or a dynamic pattern like this. And it would be very hard to keep track of which components you install where.
Three things come to my mind:
An optional
NuxtComponent-component, in which all components are installed globally (as lazy imports). Usage would be just like the usual case:<NuxtComponent :is="MyComponent">, which would lazyload theMyComponent-chunk. That would mean that some unnecessary chunks are generated whenNuxtComponentis used, but at least they would not be loaded, and it’s up users whether they decide to use it.a global nuxt.config option where you can set the components that will be globally installed to the
NuxtComponent(or even any component), ideally with the option to glob directories. As the chunks for any use of the<component>-Tag need to be generated anyway, even with the comment syntax you suggested, that would at least keep things in one place, so it seems less brittle to me. So something like this:<!-- @components /components/builder/**/*.vue -->// EDIT:
Or, option 4:
componentsto the component config:Auto import dynamic components
@gilles6 @cavi21 @samuells It’s been some time, but I was able to write down the idea and how to solve this problem. You can checkout my explanation on medium.
Nuxt.js module(s)
I prepared a nuxt module to provide a
NuxtDynamiccomponent which works as stated before: @blokwise/dynamic@samuells there is also an implementation for a wrapper which renders components based on storyblok schemas, checkout the @blokwise/blok module.
I like the 2nd option, available for any <component>, with an option to glob directories.
My personal use case is that I have a site that is built in CMS and I don’t know which sections / components will be used in advance.
A magic comment is rather strange.
Maybe something along those lines:
I would vote for option 4 of the proposal from @hv-pul with the
nuxtLazyComponents(or whatever that prop is called) being a function returning the array of component names. afaik all components in a project are indexed. mapping that array of indexed components with the defined array in specific component with thenuxtLazyComponentsdefined will make it possible to lazy load the components as dynamic components easily (at least with dynamic imports when binding the imported component instead of it’s name to the:isprop of the dynamic component in the template)Any tips on how to use this
import('~/node_modules/UILibrary/${this.component_name}')? The import route gets scrambled by I assume webpack and doesn’t work. In particular I am trying to do this with vuetify. It works when importing from~/componentsbut not when importing fromnode_modulesI would be definitely interested in some kind of way/pattern to define these dynamic components. Especially in my case using Storyblok CMS I don’t know often which components should I render. What I often know is a list of possibilities. So Option 4 looks like a way to me. 😇
It make sens to add comments like this. As in production it’s almost impossible to know before wich componnents will be there. In this case you will add all components in the bundler that is not possible.
Definitely cool. As i need it too ^^. I hope it i will come soon 😃
@kevinmarrec I wonder if there’s perhaps room to explore a similar approach to what content is doing (having a special directory that is treated as global components to always be loaded).
From https://content.nuxtjs.org/writing#table-of-contents :
@gilles6 you cannot dynamically load dynamic components as you try to do - by now at least. That’s what the whole issue is about 😉 However, I managed to build a workaround with the help of
vue-lazy-hydrationpackage. I can describe my approach to do so if you are interested.If components that could potentially be lazy loaded need to be specified (which is reasonable), then I think a
nuxtComponentsoption with an array of component names is preferable to the magic comment.The exported object is where all the other options regarding component logic live, so that’s where I’d expect to specify this kind of thing.
in terms of having a small chunk as a possible i am not a fan of having by default like global components register for dynamics. I have like 130 components in my project so… that have a lot of dynamics dependencies.
I like the idea of comments clear and simple