diff --git a/packages/nuxt3/build.config.ts b/packages/nuxt3/build.config.ts index 8030d0a9709..c09f310e3ef 100644 --- a/packages/nuxt3/build.config.ts +++ b/packages/nuxt3/build.config.ts @@ -9,7 +9,6 @@ export default defineBuildConfig({ { input: 'src/app/', outDir: 'dist/app/' }, // Runtime dirs ...[ - 'components', 'meta', 'pages' ].map(name => ({ input: `src/${name}/runtime/`, outDir: `dist/${name}/runtime`, format: 'esm' } as BuildEntry)) diff --git a/packages/nuxt3/src/app/templates.ts b/packages/nuxt3/src/app/templates.ts index a7dcd672295..f7e2f49c212 100644 --- a/packages/nuxt3/src/app/templates.ts +++ b/packages/nuxt3/src/app/templates.ts @@ -1,12 +1,11 @@ import type { Nuxt, NuxtApp } from '@nuxt/kit' -import * as templateUtils from '../core/template.utils' +import { importName, importSources } from '../core/template.utils' type TemplateContext = { nuxt: Nuxt; app: NuxtApp; - utils: typeof templateUtils } export const appTemplate = { @@ -26,11 +25,11 @@ export const cssTemplate = { export const clientPluginTemplate = { filename: 'plugins/client.mjs', getContents (ctx: TemplateContext) { - const { app, utils } = ctx + const { app } = ctx return [ - utils.importSources(app.plugins.filter(p => !p.mode || p.mode !== 'server').map(p => p.src)), + importSources(app.plugins.filter(p => !p.mode || p.mode !== 'server').map(p => p.src)), 'export default [', - app.plugins.filter(p => !p.mode || p.mode !== 'server').map(p => utils.importName(p.src)).join(',\n '), + app.plugins.filter(p => !p.mode || p.mode !== 'server').map(p => importName(p.src)).join(',\n '), ']' ].join('\n') } @@ -39,13 +38,13 @@ export const clientPluginTemplate = { export const serverPluginTemplate = { filename: 'plugins/server.mjs', getContents (ctx: TemplateContext) { - const { app, utils } = ctx + const { app } = ctx return [ "import preload from '#app/plugins/preload.server'", - utils.importSources(app.plugins.filter(p => !p.mode || p.mode !== 'client').map(p => p.src)), + importSources(app.plugins.filter(p => !p.mode || p.mode !== 'client').map(p => p.src)), 'export default [', ' preload,', - app.plugins.filter(p => !p.mode || p.mode !== 'client').map(p => utils.importName(p.src)).join(',\n '), + app.plugins.filter(p => !p.mode || p.mode !== 'client').map(p => importName(p.src)).join(',\n '), ']' ].join('\n') } diff --git a/packages/nuxt3/src/components/module.ts b/packages/nuxt3/src/components/module.ts index 06baad6d755..cf39e34b2a4 100644 --- a/packages/nuxt3/src/components/module.ts +++ b/packages/nuxt3/src/components/module.ts @@ -1,7 +1,7 @@ import { statSync } from 'fs' -import { resolve, relative } from 'upath' +import { resolve } from 'upath' import { defineNuxtModule, resolveAlias, addVitePlugin, addWebpackPlugin } from '@nuxt/kit' -import { distDir } from '../dirs' +import { componentsTemplate, componentsTypeTemplate } from './templates' import { scanComponents } from './scan' import type { Component, ComponentsDir } from './types' import { loaderPlugin } from './loader' @@ -66,19 +66,13 @@ export default defineNuxtModule({ } app.templates.push({ - filename: 'components.mjs', - src: resolve(distDir, 'components/runtime/components.tmpl.mjs'), + ...componentsTemplate, options: { components } }) app.templates.push({ - filename: 'components.d.ts', - write: true, - getContents: () => `// Generated by components discovery -declare module 'vue' { - export interface GlobalComponents { -${components.map(c => ` '${c.pascalName}': typeof import('${relative(nuxt.options.buildDir, c.filePath)}')['${c.export}']`).join(',\n')} - }\n}\n\nexport {}` + ...componentsTypeTemplate, + options: { components, buildDir: nuxt.options.buildDir } }) app.plugins.push({ src: '#build/components' }) diff --git a/packages/nuxt3/src/components/runtime/components.tmpl.mjs b/packages/nuxt3/src/components/runtime/components.tmpl.mjs deleted file mode 100644 index d34d0d6332e..00000000000 --- a/packages/nuxt3/src/components/runtime/components.tmpl.mjs +++ /dev/null @@ -1,22 +0,0 @@ - -import { defineAsyncComponent } from 'vue' - -const components = { -<%= components.map(c => { - const exp = c.export === 'default' ? `c.default || c` : `c['${c.export}']` - const magicComments = [ - `webpackChunkName: "${c.chunkName}"`, - c.prefetch === true || typeof c.prefetch === 'number' ? `webpackPrefetch: ${c.prefetch}` : false, - c.preload === true || typeof c.preload === 'number' ? `webpackPreload: ${c.preload}` : false, - ].filter(Boolean).join(', ') - - return ` '${c.pascalName}': defineAsyncComponent(() => import('${c.filePath}' /* ${magicComments} */).then(c => ${exp}))` -}).join(',\n') %> -} - -export default function (nuxt) { - for (const name in components) { - nuxt.app.component(name, components[name]) - nuxt.app.component('Lazy' + name, components[name]) - } -} diff --git a/packages/nuxt3/src/components/templates.ts b/packages/nuxt3/src/components/templates.ts new file mode 100644 index 00000000000..d729b3f4c01 --- /dev/null +++ b/packages/nuxt3/src/components/templates.ts @@ -0,0 +1,61 @@ + +import { relative } from 'upath' + +import type { Component } from './types' + +export type ComponentsTemplateOptions = { + buildDir?: string + components: Component[] +} + +export type ImportMagicCommentsOptions = { + chunkName:string + prefetch?: boolean | number + preload?: boolean | number +} + +const createImportMagicComments = (options: ImportMagicCommentsOptions) => { + const { chunkName, prefetch, preload } = options + return [ + `webpackChunkName: "${chunkName}"`, + prefetch === true || typeof prefetch === 'number' ? `webpackPrefetch: ${prefetch}` : false, + preload === true || typeof preload === 'number' ? `webpackPreload: ${preload}` : false + ].filter(Boolean).join(', ') +} + +export const componentsTemplate = { + filename: 'components.mjs', + getContents (options: ComponentsTemplateOptions) { + return `import { defineAsyncComponent } from 'vue' + +const components = { +${options.components.map((c) => { + const exp = c.export === 'default' ? 'c.default || c' : `c['${c.export}']` + const magicComments = createImportMagicComments(c) + + return ` '${c.pascalName}': defineAsyncComponent(() => import('${c.filePath}' /* ${magicComments} */).then(c => ${exp}))` +}).join(',\n')} +} + +export default function (nuxt) { + for (const name in components) { + nuxt.app.component(name, components[name]) + nuxt.app.component('Lazy' + name, components[name]) + } +} +` + } +} + +export const componentsTypeTemplate = { + filename: 'components.d.ts', + write: true, + getContents: (options: ComponentsTemplateOptions) => `// Generated by components discovery +declare module 'vue' { + export interface GlobalComponents { +${options.components.map(c => ` '${c.pascalName}': typeof import('${relative(options.buildDir, c.filePath)}')['${c.export}']`).join(',\n')} + } + + export {} +}` +}