Crank up auto import for dynamic Nuxt.js components
Auto import all the things 🚀
Back in the days we used to import all those components into every single
.vue file — import and registering them over and over again became a tedious task.
Then the awesome Nuxt.js team released
@nuxt/components to auto import project and third party library specific components 🚀 No more imports were necessary. No more component registering.
That’s it! Clean projects, clean components, clean webpack chunks.
That’s what I thought at least.
What about Headless CMS’s?
At our digital agency we have a bunch of projects using headless CMS’s — Storyblok as one among them. Storyblok gives the developer and the customer the freedom to nest components in all possible ways — dynamically.
So we wanted to load the components dynamically.
That’s not possible at the time of this writing — at least not with
@nuxt/components out of the box (issue #43).
So I decided to dig some code — Let’s see how this Nuxt.js module works.
It looks like the module gets components based on what’s passed to the
It prepares an array of components with their component names (PascalCase and kebab-case) and their relative filepaths.
In a second step all
.vue files will be scanned to load the components used in a given template (and to import those components). That’s why the auto import for a dynamic component does not work at all.
Back to the roots — import all those components manually? All of the 14328 possibilities?
Well then — Let’s try to figure out how we can solve that problem.
The underlying magic
Alright then: a dynamic component can be rendered if we pass a component name of an imported vue component or if we pass the component itself. Remember:
@nuxt/components is aware of every relative path for the auto importing mechanism. So if we could make dynamic webpack imports with those paths available inside a component we are able to load its children.
Plugin to the rescue
We are able to hook into the
components:extend hook and grab all the component names when we build a module.
Now we construct dynamic import statements for all components inside a plugin which injects the loaders into each vue component.
This translates to something like this:
That was an easy one, amirite?
Hydrate all the things
Now it’s possible to execute the injected async import to load a specific component — we will use
vue-lazy-hydration to do so (big thanks to Markus Oberlehner).
After executing the lazy import, the loaded component can be passed to the :is prop.
NuxtDynamic can now be used to auto import every dynamic component.
That’s it, we did it! Nuxt.js auto imports dynamic components 🚀
The official docs for
@blokwise/dynamic can be found at dynamic.blokwise.io.