diff --git a/examples/with-components/nuxt.d.ts b/examples/with-components/nuxt.d.ts
new file mode 100644
index 0000000000..40e13c8b3e
--- /dev/null
+++ b/examples/with-components/nuxt.d.ts
@@ -0,0 +1,11 @@
+// This file is auto generated by `nuxt prepare`
+// Please do not manually modify this file.
+
+///
+///
+///
+///
+///
+///
+///
+export {}
diff --git a/packages/cli/src/commands/prepare.ts b/packages/cli/src/commands/prepare.ts
index 35bcdf10d7..8916d832af 100644
--- a/packages/cli/src/commands/prepare.ts
+++ b/packages/cli/src/commands/prepare.ts
@@ -45,7 +45,12 @@ export default defineNuxtCommand({
'// This file is auto generated by `nuxt prepare`',
'// Please do not manually modify this file.',
'',
- ...references.map(ref => `/// `),
+ ...references.map((ref) => {
+ if ('path' in ref) {
+ ref.path = relative(rootDir, ref.path)
+ }
+ return `/// `
+ }),
...declarations,
'export {}',
''
diff --git a/packages/components/src/module.ts b/packages/components/src/module.ts
index 5371302fa2..9725ec7357 100644
--- a/packages/components/src/module.ts
+++ b/packages/components/src/module.ts
@@ -1,12 +1,12 @@
-import fs from 'fs'
+import { statSync } from 'fs'
+import { resolve, relative } from 'upath'
import { defineNuxtModule, resolveAlias, addVitePlugin, addWebpackPlugin } from '@nuxt/kit'
-import { resolve } from 'upath'
import { scanComponents } from './scan'
import type { Component, ComponentsDir } from './types'
import { loaderPlugin } from './loader'
const isPureObjectOrString = (val: any) => (!Array.isArray(val) && typeof val === 'object') || typeof val === 'string'
-const isDirectory = (p: string) => { try { return fs.statSync(p).isDirectory() } catch (_e) { return false } }
+const isDirectory = (p: string) => { try { return statSync(p).isDirectory() } catch (_e) { return false } }
export default defineNuxtModule({
name: 'components',
@@ -72,13 +72,21 @@ export default defineNuxtModule({
app.templates.push({
filename: 'components.d.ts',
- src: resolve(__dirname, 'runtime/components.tmpl.d.ts'),
- options: { components }
+ 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 {}`
})
app.plugins.push({ src: '#build/components' })
})
+ nuxt.hook('prepare:types', ({ references }) => {
+ references.push({ path: resolve(nuxt.options.buildDir, 'components.d.ts') })
+ })
+
// Watch for changes
nuxt.hook('builder:watch', async (event, path) => {
if (!['add', 'unlink'].includes(event)) {
diff --git a/packages/components/src/runtime/components.tmpl.d.ts b/packages/components/src/runtime/components.tmpl.d.ts
deleted file mode 100644
index b60d82ecb6..0000000000
--- a/packages/components/src/runtime/components.tmpl.d.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-declare module 'vue' {
- export interface GlobalComponents {
-<%= components.map(c => {
- return ` '${c.pascalName}': typeof import('${c.filePath}')['${c.export}']`
-}).join(',\n') %>
- }
-}
-
-// export required to turn this into a module for TS augmentation purposes
-export { }