diff --git a/packages/bridge/src/app.ts b/packages/bridge/src/app.ts index 25744700a0..baa22d00fd 100644 --- a/packages/bridge/src/app.ts +++ b/packages/bridge/src/app.ts @@ -35,7 +35,7 @@ export function setupAppBridge (_options: any) { options: { components, buildDir: nuxt.options.buildDir } }) nuxt.hook('prepare:types', ({ references }) => { - references.push({ path: resolve(nuxt.options.buildDir, 'components.d.ts') }) + references.push({ path: resolve(nuxt.options.buildDir, 'types/components.d.ts') }) }) // Alias vue to have identical vue3 exports diff --git a/packages/bridge/src/nitro.ts b/packages/bridge/src/nitro.ts index 73f1e4297f..f8d63fa7b7 100644 --- a/packages/bridge/src/nitro.ts +++ b/packages/bridge/src/nitro.ts @@ -143,7 +143,7 @@ export function setupNitroBridge () { // Add typed route responses nuxt.hook('prepare:types', (opts) => { - opts.references.push({ path: resolve(nuxt.options.buildDir, 'nitro.d.ts') }) + opts.references.push({ path: resolve(nuxt.options.buildDir, 'types/nitro.d.ts') }) }) // nuxt prepare diff --git a/packages/kit/src/template.ts b/packages/kit/src/template.ts index 5979d32d45..06d709b868 100644 --- a/packages/kit/src/template.ts +++ b/packages/kit/src/template.ts @@ -58,6 +58,11 @@ export function normalizeTemplate (template: NuxtTemplate | string): NuxtTemplat throw new Error('Invalid template. Either filename should be provided: ' + JSON.stringify(template)) } + // Always write declaration files + if (template.filename.endsWith('.d.ts')) { + template.write = true + } + // Resolve dst if (!template.dst) { const nuxt = useNuxt() diff --git a/packages/nitro/src/build.ts b/packages/nitro/src/build.ts index 1e8e9e5f7b..bdf2ddbd7c 100644 --- a/packages/nitro/src/build.ts +++ b/packages/nitro/src/build.ts @@ -88,7 +88,7 @@ export async function writeTypes (nitroContext: NitroContext) { 'export {}' ] - await writeFile(join(nitroContext._nuxt.buildDir, 'nitro.d.ts'), lines.join('\n')) + await writeFile(join(nitroContext._nuxt.buildDir, 'types/nitro.d.ts'), lines.join('\n')) } async function _build (nitroContext: NitroContext) { diff --git a/packages/nuxi/src/utils/prepare.ts b/packages/nuxi/src/utils/prepare.ts index 28c3b0ba38..f42dcc1ead 100644 --- a/packages/nuxi/src/utils/prepare.ts +++ b/packages/nuxi/src/utils/prepare.ts @@ -1,5 +1,5 @@ import { promises as fsp } from 'fs' -import { join, relative, resolve } from 'pathe' +import { isAbsolute, join, relative, resolve } from 'pathe' import { Nuxt, TSReference } from '@nuxt/schema' import defu from 'defu' import type { TSConfig } from 'pkg-types' @@ -46,7 +46,9 @@ export const writeTypes = async (nuxt: Nuxt) => { if (excludedAlias.some(re => re.test(alias))) { continue } - const relativePath = relative(nuxt.options.rootDir, aliases[alias]).replace(/(?<=\w)\.\w+$/g, '') /* remove extension */ || '.' + const relativePath = isAbsolute(aliases[alias]) + ? relative(nuxt.options.rootDir, aliases[alias]).replace(/(?<=\w)\.\w+$/g, '') /* remove extension */ || '.' + : aliases[alias] tsConfig.compilerOptions.paths[alias] = [relativePath] try { @@ -71,7 +73,7 @@ export const writeTypes = async (nuxt: Nuxt) => { const declaration = [ ...references.map((ref) => { - if ('path' in ref) { + if ('path' in ref && isAbsolute(ref.path)) { ref.path = relative(nuxt.options.buildDir, ref.path) } return `/// ` diff --git a/packages/nuxt3/src/auto-imports/module.ts b/packages/nuxt3/src/auto-imports/module.ts index 4674298cd7..cbdec2db0a 100644 --- a/packages/nuxt3/src/auto-imports/module.ts +++ b/packages/nuxt3/src/auto-imports/module.ts @@ -91,8 +91,8 @@ export default defineNuxtModule({ // Add generated types to `nuxt.d.ts` nuxt.hook('prepare:types', ({ references }) => { - references.push({ path: resolve(nuxt.options.buildDir, 'auto-imports.d.ts') }) - references.push({ path: resolve(nuxt.options.buildDir, 'imports.d.ts') }) + references.push({ path: resolve(nuxt.options.buildDir, 'types/auto-imports.d.ts') }) + references.push({ path: resolve(nuxt.options.buildDir, 'types/imports.d.ts') }) }) // Watch composables/ directory @@ -113,7 +113,7 @@ function generateDts (ctx: AutoImportContext) { if (resolved[id]) { return resolved[id] } let path = resolveAlias(id, nuxt.options.alias) if (isAbsolute(path)) { - path = relative(nuxt.options.buildDir, path) + path = relative(join(nuxt.options.buildDir, 'types'), path) } // Remove file extension for benefit of TypeScript path = path.replace(/\.[a-z]+$/, '') @@ -122,13 +122,13 @@ function generateDts (ctx: AutoImportContext) { } addTemplate({ - filename: 'imports.d.ts', + filename: 'types/imports.d.ts', write: true, getContents: () => toExports(ctx.autoImports) }) addTemplate({ - filename: 'auto-imports.d.ts', + filename: 'types/auto-imports.d.ts', write: true, getContents: () => `// Generated by auto imports declare global { diff --git a/packages/nuxt3/src/components/module.ts b/packages/nuxt3/src/components/module.ts index 203b3f0994..7b6ccb7509 100644 --- a/packages/nuxt3/src/components/module.ts +++ b/packages/nuxt3/src/components/module.ts @@ -84,7 +84,7 @@ export default defineNuxtModule({ }) nuxt.hook('prepare:types', ({ references }) => { - references.push({ path: resolve(nuxt.options.buildDir, 'components.d.ts') }) + references.push({ path: resolve(nuxt.options.buildDir, 'types/components.d.ts') }) }) // Watch for changes diff --git a/packages/nuxt3/src/components/templates.ts b/packages/nuxt3/src/components/templates.ts index 1652796b6f..d301e2016a 100644 --- a/packages/nuxt3/src/components/templates.ts +++ b/packages/nuxt3/src/components/templates.ts @@ -1,5 +1,5 @@ -import { relative } from 'pathe' +import { isAbsolute, join, relative } from 'pathe' import type { Component } from '@nuxt/schema' export type ComponentsTemplateOptions = { @@ -47,12 +47,11 @@ export default function (nuxtApp) { } export const componentsTypeTemplate = { - filename: 'components.d.ts', - write: true, + filename: 'types/components.d.ts', getContents: ({ options }: { 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')} +${options.components.map(c => ` '${c.pascalName}': typeof import('${isAbsolute(c.filePath) ? relative(join(options.buildDir, 'types'), c.filePath) : c.filePath}')['${c.export}']`).join(',\n')} } } export {} diff --git a/packages/nuxt3/src/core/app.ts b/packages/nuxt3/src/core/app.ts index cc11dbb4a7..19940b5b87 100644 --- a/packages/nuxt3/src/core/app.ts +++ b/packages/nuxt3/src/core/app.ts @@ -1,5 +1,5 @@ import { promises as fsp } from 'fs' -import { resolve } from 'pathe' +import { dirname, resolve } from 'pathe' import defu from 'defu' import type { Nuxt, NuxtApp } from '@nuxt/schema' import { tryResolvePath, resolveFiles, normalizePlugin, normalizeTemplate, compileTemplate, templateUtils } from '@nuxt/kit' @@ -45,6 +45,7 @@ export async function generateApp (nuxt: Nuxt, app: NuxtApp) { } if (template.write) { + await fsp.mkdir(dirname(fullPath), { recursive: true }) await fsp.writeFile(fullPath, contents, 'utf8') } })) diff --git a/packages/nuxt3/src/core/nitro.ts b/packages/nuxt3/src/core/nitro.ts index f2ec695507..c387d580dd 100644 --- a/packages/nuxt3/src/core/nitro.ts +++ b/packages/nuxt3/src/core/nitro.ts @@ -41,7 +41,7 @@ export function initNitro (nuxt: Nuxt) { // Add typed route responses nuxt.hook('prepare:types', (opts) => { - opts.references.push({ path: resolve(nuxt.options.buildDir, 'nitro.d.ts') }) + opts.references.push({ path: resolve(nuxt.options.buildDir, 'types/nitro.d.ts') }) }) // Add nitro client plugin (to inject $fetch helper) diff --git a/packages/nuxt3/src/core/nuxt.ts b/packages/nuxt3/src/core/nuxt.ts index 6d70d95f89..aeef3c4718 100644 --- a/packages/nuxt3/src/core/nuxt.ts +++ b/packages/nuxt3/src/core/nuxt.ts @@ -44,10 +44,10 @@ async function initNuxt (nuxt: Nuxt) { // Add nuxt3 types nuxt.hook('prepare:types', (opts) => { opts.references.push({ types: 'nuxt3' }) - opts.references.push({ path: resolve(nuxt.options.buildDir, 'plugins.d.ts') }) + opts.references.push({ path: resolve(nuxt.options.buildDir, 'types/plugins.d.ts') }) // Add vue shim if (nuxt.options.typescript.shim) { - opts.references.push({ path: resolve(nuxt.options.buildDir, 'vue-shim.d.ts') }) + opts.references.push({ path: resolve(nuxt.options.buildDir, 'types/vue-shim.d.ts') }) } }) diff --git a/packages/nuxt3/src/core/templates.ts b/packages/nuxt3/src/core/templates.ts index 4b75f907e3..47c4251a82 100644 --- a/packages/nuxt3/src/core/templates.ts +++ b/packages/nuxt3/src/core/templates.ts @@ -1,7 +1,7 @@ import { templateUtils } from '@nuxt/kit' import type { Nuxt, NuxtApp } from '@nuxt/schema' -import { relative } from 'pathe' +import { isAbsolute, join, relative } from 'pathe' import escapeRE from 'escape-string-regexp' type TemplateContext = { @@ -10,8 +10,7 @@ type TemplateContext = { } export const vueShim = { - filename: 'vue-shim.d.ts', - write: true, + filename: 'types/vue-shim.d.ts', getContents: () => [ 'declare module \'*.vue\' {', @@ -92,11 +91,10 @@ export const appViewTemplate = { } export const pluginsDeclaration = { - filename: 'plugins.d.ts', - write: true, + filename: 'types/plugins.d.ts', getContents: (ctx: TemplateContext) => { const EXTENSION_RE = new RegExp(`(?<=\\w)(${ctx.nuxt.options.extensions.map(e => escapeRE(e)).join('|')})$`, 'g') - const tsImports = ctx.app.plugins.map(p => relative(ctx.nuxt.options.buildDir, p.src).replace(EXTENSION_RE, '')) + const tsImports = ctx.app.plugins.map(p => (isAbsolute(p.src) ? relative(join(ctx.nuxt.options.buildDir, 'types'), p.src) : p.src).replace(EXTENSION_RE, '')) return `// Generated by Nuxt3' import type { Plugin } from '#app' diff --git a/packages/nuxt3/src/pages/module.ts b/packages/nuxt3/src/pages/module.ts index 8fbd60b00b..dafc3d368e 100644 --- a/packages/nuxt3/src/pages/module.ts +++ b/packages/nuxt3/src/pages/module.ts @@ -102,8 +102,7 @@ export default defineNuxtModule({ }) addTemplate({ - filename: 'middleware.d.ts', - write: true, + filename: 'types/middleware.d.ts', getContents: async () => { const composablesFile = resolve(runtimeDir, 'composables') const middleware = await resolveMiddleware() @@ -121,8 +120,7 @@ export default defineNuxtModule({ }) addTemplate({ - filename: 'layouts.d.ts', - write: true, + filename: 'types/layouts.d.ts', getContents: async () => { const composablesFile = resolve(runtimeDir, 'composables') const layouts = await resolveLayouts(nuxt) @@ -155,8 +153,8 @@ export default defineNuxtModule({ // Add declarations for middleware and layout keys nuxt.hook('prepare:types', ({ references }) => { - references.push({ path: resolve(nuxt.options.buildDir, 'middleware.d.ts') }) - references.push({ path: resolve(nuxt.options.buildDir, 'layouts.d.ts') }) + references.push({ path: resolve(nuxt.options.buildDir, 'types/middleware.d.ts') }) + references.push({ path: resolve(nuxt.options.buildDir, 'types/layouts.d.ts') }) }) } })