Skip to content
This repository has been archived by the owner on Apr 6, 2023. It is now read-only.

feat(nuxt): allow programmatically prefetching global components #6661

Merged
merged 13 commits into from
Aug 23, 2022
Merged
1 change: 1 addition & 0 deletions packages/nuxt/src/app/nuxt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export interface RuntimeNuxtHooks {
'app:error': (err: any) => HookResult
'app:error:cleared': (options: { redirect?: string }) => HookResult
'app:data:refresh': (keys?: string[]) => HookResult
'components:prefetch': (component: string | string[]) => HookResult
'page:start': (Component?: VNode) => HookResult
'page:finish': (Component?: VNode) => HookResult
'meta:register': (metaRenderers: Array<(nuxt: NuxtApp) => NuxtMeta | Promise<NuxtMeta>>) => HookResult
Expand Down
18 changes: 17 additions & 1 deletion packages/nuxt/src/components/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export interface ComponentsTemplateContext {
}

export type ImportMagicCommentsOptions = {
chunkName:string
chunkName: string
prefetch?: boolean | number
preload?: boolean | number
}
Expand Down Expand Up @@ -40,7 +40,23 @@ const components = ${genObjectFromRawEntries(globalComponents.map((c) => {
return [c.pascalName, `defineAsyncComponent(${genDynamicImport(c.filePath, { comment })}.then(c => ${exp}))`]
}))}

function prefetchAsyncComponent (component) {
if (component?.__asyncLoader && !component.__asyncResolved) {
return component.__asyncLoader()
}
}

export default defineNuxtPlugin(nuxtApp => {
if (process.client) {
nuxtApp.hook('components:prefetch', async (components) => {
danielroe marked this conversation as resolved.
Show resolved Hide resolved
components = Array.isArray(components) ? components : [components]
await Promise.all(components.map((name) => {
if (name in components) {
return prefetchAsyncComponent(components[name])
}
}))
})
}
for (const name in components) {
nuxtApp.vueApp.component(name, components[name])
nuxtApp.vueApp.component('Lazy' + name, components[name])
Expand Down