diff --git a/packages/nuxt/src/core/nitro.ts b/packages/nuxt/src/core/nitro.ts index 291752fce6..0031ecb085 100644 --- a/packages/nuxt/src/core/nitro.ts +++ b/packages/nuxt/src/core/nitro.ts @@ -49,7 +49,19 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) { .map(m => m.entryPath!), ) + const sharedDirs = new Set() const isNuxtV4 = nuxt.options.future?.compatibilityVersion === 4 + if (isNuxtV4 && (nuxt.options.nitro.imports !== false && nuxt.options.imports.scan !== false)) { + for (const layer of nuxt.options._layers) { + // Layer disabled scanning for itself + if (layer.config?.imports?.scan === false) { + continue + } + + sharedDirs.add(resolve(layer.config.rootDir, 'shared', 'utils')) + sharedDirs.add(resolve(layer.config.rootDir, 'shared', 'types')) + } + } const nitroConfig: NitroConfig = defu(nuxt.options.nitro, { debug: nuxt.options.debug ? nuxt.options.debug.nitro : false, @@ -68,12 +80,7 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) { }, imports: { autoImport: nuxt.options.imports.autoImport as boolean, - dirs: isNuxtV4 - ? [ - resolve(nuxt.options.rootDir, 'shared', 'utils'), - resolve(nuxt.options.rootDir, 'shared', 'types'), - ] - : [], + dirs: [...sharedDirs], imports: [ { as: '__buildAssetsURL', diff --git a/packages/nuxt/test/shared-dir-config.test.ts b/packages/nuxt/test/shared-dir-config.test.ts new file mode 100644 index 0000000000..c066a98327 --- /dev/null +++ b/packages/nuxt/test/shared-dir-config.test.ts @@ -0,0 +1,57 @@ +import { fileURLToPath } from 'node:url' +import { describe, expect, it } from 'vitest' +import { normalize } from 'pathe' +import type { NuxtConfig } from '@nuxt/schema' +import { loadNuxt } from '../src' + +const fixtureDir = normalize(fileURLToPath(new URL('../../../test/fixtures/basic', import.meta.url))) + +describe('loadNuxt', () => { + it('does not add shared directories to nitro auto-imports in v3', async () => { + const importDirs = await getNitroImportDirs({ future: { compatibilityVersion: 3 as any } }) + expect(normalizePaths(importDirs)).toMatchInlineSnapshot(`[]`) + }) + it('adds shared directories for layers to nitro auto-imports in v4', async () => { + const importDirs = await getNitroImportDirs({ future: { compatibilityVersion: 4 } }) + expect(normalizePaths(importDirs)).toMatchInlineSnapshot(` + [ + "/shared/utils", + "/shared/types", + "/extends/bar/shared/utils", + "/extends/bar/shared/types", + "/extends/node_modules/foo/shared/utils", + "/extends/node_modules/foo/shared/types", + "/layers/bar/shared/utils", + "/layers/bar/shared/types", + ] + `) + }) +}) + +function normalizePaths (arr: unknown[]) { + const normalized = [] + for (const dir of arr) { + normalized.push(typeof dir === 'string' ? dir.replace(fixtureDir, '') : dir) + } + return normalized +} + +async function getNitroImportDirs (overrides?: NuxtConfig) { + const importDirs: unknown[] = [] + const nuxt = await loadNuxt({ + cwd: fixtureDir, + ready: true, + overrides: { + ...overrides, + hooks: { + 'nitro:config' (config) { + if (config.imports) { + importDirs.push(...config.imports.dirs || []) + } + }, + }, + }, + }) + await nuxt.close() + return importDirs +}