diff --git a/packages/nuxi/src/utils/prepare.ts b/packages/nuxi/src/utils/prepare.ts index d428f7782c..79aa930093 100644 --- a/packages/nuxi/src/utils/prepare.ts +++ b/packages/nuxi/src/utils/prepare.ts @@ -48,6 +48,8 @@ export const writeTypes = async (nuxt: Nuxt) => { const basePath = tsConfig.compilerOptions!.baseUrl ? resolve(nuxt.options.buildDir, tsConfig.compilerOptions!.baseUrl) : nuxt.options.buildDir + tsConfig.compilerOptions = tsConfig.compilerOptions || {} + for (const alias in aliases) { if (excludedAlias.some(re => re.test(alias))) { continue @@ -55,7 +57,6 @@ export const writeTypes = async (nuxt: Nuxt) => { const absolutePath = resolve(basePath, aliases[alias]) const stats = await fsp.stat(absolutePath).catch(() => null /* file does not exist */) - tsConfig.compilerOptions = tsConfig.compilerOptions || {} if (stats?.isDirectory()) { tsConfig.compilerOptions.paths[alias] = [absolutePath] tsConfig.compilerOptions.paths[`${alias}/*`] = [`${absolutePath}/*`] diff --git a/packages/nuxt/src/core/nitro.ts b/packages/nuxt/src/core/nitro.ts index a40a9ed8c1..ac8fb0de8b 100644 --- a/packages/nuxt/src/core/nitro.ts +++ b/packages/nuxt/src/core/nitro.ts @@ -38,7 +38,7 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) { } } - const nitroConfig: NitroConfig = defu(_nitroConfig, { + const nitroConfig: NitroConfig = defu(_nitroConfig, { static: nuxt.options._generate, debug: nuxt.options.debug, rootDir: nuxt.options.rootDir, @@ -47,7 +47,7 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) { dev: nuxt.options.dev, buildDir: nuxt.options.buildDir, imports: { - autoImport: nuxt.options.imports.autoImport, + autoImport: nuxt.options.imports.autoImport as boolean, imports: [ { as: '__buildAssetsURL', @@ -112,7 +112,12 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) { typescript: { strict: true, generateTsConfig: true, - tsconfigPath: 'tsconfig.server.json' + tsconfigPath: 'tsconfig.server.json', + tsConfig: { + include: [ + join(nuxt.options.buildDir, 'types/nitro-nuxt.d.ts') + ] + } }, publicAssets: [ nuxt.options.dev @@ -143,7 +148,7 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) { '@nuxt/', nuxt.options.buildDir ]), - ...nuxt.options.build.transpile.filter(i => typeof i === 'string'), + ...nuxt.options.build.transpile.filter((i): i is string => typeof i === 'string'), 'nuxt/dist', 'nuxt3/dist', distDir @@ -202,7 +207,7 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) { output: {}, plugins: [] } - }) + } satisfies NitroConfig) // Resolve user-provided paths nitroConfig.srcDir = resolve(nuxt.options.rootDir, nuxt.options.srcDir, nitroConfig.srcDir!) @@ -256,6 +261,30 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) { // Extend nitro config with hook await nuxt.callHook('nitro:config', nitroConfig) + // TODO: extract to shared utility? + const excludedAlias = [/^@vue\/.*$/, '#imports', '#vue-router', 'vue-demi', /^#app/] + const basePath = nitroConfig.typescript!.tsConfig!.compilerOptions?.baseUrl ? resolve(nuxt.options.buildDir, nitroConfig.typescript!.tsConfig!.compilerOptions?.baseUrl) : nuxt.options.buildDir + const aliases = nitroConfig.alias! + const tsConfig = nitroConfig.typescript!.tsConfig! + tsConfig.compilerOptions = tsConfig.compilerOptions || {} + tsConfig.compilerOptions.paths = tsConfig.compilerOptions.paths || {} + for (const _alias in aliases) { + const alias = _alias as keyof typeof aliases + if (excludedAlias.some(pattern => typeof pattern === 'string' ? alias === pattern : pattern.test(alias))) { + continue + } + if (alias in tsConfig.compilerOptions.paths) { continue } + + const absolutePath = resolve(basePath, aliases[alias]!) + const stats = await fsp.stat(absolutePath).catch(() => null /* file does not exist */) + if (stats?.isDirectory()) { + tsConfig.compilerOptions.paths[alias] = [absolutePath] + tsConfig.compilerOptions.paths[`${alias}/*`] = [`${absolutePath}/*`] + } else { + tsConfig.compilerOptions.paths[alias] = [absolutePath.replace(/(?<=\w)\.\w+$/g, '')] /* remove extension */ + } + } + // Init nitro const nitro = await createNitro(nitroConfig) diff --git a/packages/nuxt/src/core/nuxt.ts b/packages/nuxt/src/core/nuxt.ts index 12bc21c8a6..0fbc884d35 100644 --- a/packages/nuxt/src/core/nuxt.ts +++ b/packages/nuxt/src/core/nuxt.ts @@ -1,7 +1,7 @@ import { join, normalize, relative, resolve } from 'pathe' import { createDebugger, createHooks } from 'hookable' import type { LoadNuxtOptions } from '@nuxt/kit' -import { addBuildPlugin, addComponent, addPlugin, addVitePlugin, addWebpackPlugin, installModule, loadNuxtConfig, logger, nuxtCtx, resolveAlias, resolveFiles, resolvePath, tryResolveModule } from '@nuxt/kit' +import { addBuildPlugin, addComponent, addPlugin, addTemplate, addVitePlugin, addWebpackPlugin, installModule, loadNuxtConfig, logger, nuxtCtx, resolveAlias, resolveFiles, resolvePath, tryResolveModule } from '@nuxt/kit' import type { Nuxt, NuxtHooks, NuxtOptions } from 'nuxt/schema' import escapeRE from 'escape-string-regexp' @@ -154,6 +154,14 @@ async function initNuxt (nuxt: Nuxt) { // Transpile #app if it is imported directly from subpath export nuxt.options.build.transpile.push('nuxt/app') + // This is currently a placeholder for future augmentations that need to be applied in Nitro context + addTemplate({ + filename: 'types/nitro-nuxt.d.ts', + getContents: () => { + return 'export {}' + } + }) + // Transpile layers within node_modules nuxt.options.build.transpile.push( ...nuxt.options._layers.filter(i => i.cwd.includes('node_modules')).map(i => i.cwd as string) diff --git a/playground/server/tsconfig.json b/playground/server/tsconfig.json new file mode 100644 index 0000000000..b9ed69c19e --- /dev/null +++ b/playground/server/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../.nuxt/tsconfig.server.json" +}