diff --git a/packages/kit/src/ignore.ts b/packages/kit/src/ignore.ts index 825c3dbb6c..76e181df62 100644 --- a/packages/kit/src/ignore.ts +++ b/packages/kit/src/ignore.ts @@ -1,6 +1,6 @@ import { existsSync, readFileSync } from 'node:fs' import ignore from 'ignore' -import { join, relative } from 'pathe' +import { join, relative, resolve } from 'pathe' import { tryUseNuxt } from './context' /** @@ -16,14 +16,7 @@ export function isIgnored (pathname: string): boolean { if (!nuxt._ignore) { nuxt._ignore = ignore(nuxt.options.ignoreOptions) - const resolvedIgnore = nuxt.options.ignore.flatMap(s => resolveGroupSyntax(s)) - - nuxt._ignore.add(resolvedIgnore) - - const nuxtignoreFile = join(nuxt.options.rootDir, '.nuxtignore') - if (existsSync(nuxtignoreFile)) { - nuxt._ignore.add(readFileSync(nuxtignoreFile, 'utf-8')) - } + nuxt._ignore.add(resolveIgnorePatterns()) } const cwds = nuxt.options._layers?.map(layer => layer.cwd).sort((a, b) => b.length - a.length) @@ -35,6 +28,31 @@ export function isIgnored (pathname: string): boolean { return !!(relativePath && nuxt._ignore.ignores(relativePath)) } +export function resolveIgnorePatterns (relativePath?: string): string[] { + const nuxt = tryUseNuxt() + + // Happens with CLI reloads + if (!nuxt) { + return [] + } + + if (!nuxt._ignorePatterns) { + nuxt._ignorePatterns = nuxt.options.ignore.flatMap(s => resolveGroupSyntax(s)) + + const nuxtignoreFile = join(nuxt.options.rootDir, '.nuxtignore') + if (existsSync(nuxtignoreFile)) { + const contents = readFileSync(nuxtignoreFile, 'utf-8') + nuxt._ignorePatterns.push(...contents.trim().split(/\r?\n/)) + } + } + + if (relativePath) { + return nuxt._ignorePatterns.map(p => p.startsWith('*') || p.startsWith('!*') ? p : relative(relativePath, resolve(nuxt.options.rootDir, p))) + } + + return nuxt._ignorePatterns +} + /** * This function turns string containing groups '**\/*.{spec,test}.{js,ts}' into an array of strings. * For example will '**\/*.{spec,test}.{js,ts}' be resolved to: diff --git a/packages/kit/src/index.ts b/packages/kit/src/index.ts index cdbba6e351..da2fe614ad 100644 --- a/packages/kit/src/index.ts +++ b/packages/kit/src/index.ts @@ -14,7 +14,7 @@ export * from './build' export * from './compatibility' export * from './components' export * from './context' -export { isIgnored } from './ignore' +export { isIgnored, resolveIgnorePatterns } from './ignore' export * from './layout' export * from './pages' export * from './plugin' diff --git a/packages/nuxt/src/core/nitro.ts b/packages/nuxt/src/core/nitro.ts index 80f66b0892..917df7dc35 100644 --- a/packages/nuxt/src/core/nitro.ts +++ b/packages/nuxt/src/core/nitro.ts @@ -3,7 +3,7 @@ import { cpus } from 'node:os' import { join, relative, resolve } from 'pathe' import { build, copyPublicAssets, createDevServer, createNitro, prepare, prerender, scanHandlers, writeTypes } from 'nitropack' import type { Nitro, NitroConfig } from 'nitropack' -import { logger } from '@nuxt/kit' +import { logger, resolveIgnorePatterns } from '@nuxt/kit' import escapeRE from 'escape-string-regexp' import { defu } from 'defu' import fsExtra from 'fs-extra' @@ -207,6 +207,7 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) { // Resolve user-provided paths nitroConfig.srcDir = resolve(nuxt.options.rootDir, nuxt.options.srcDir, nitroConfig.srcDir!) + nitroConfig.ignore = [...(nitroConfig.ignore || []), ...resolveIgnorePatterns(nitroConfig.srcDir)] // Add fallback server for `ssr: false` if (!nuxt.options.ssr) { diff --git a/packages/schema/src/types/nuxt.ts b/packages/schema/src/types/nuxt.ts index 52f68bb60d..224c1190ca 100644 --- a/packages/schema/src/types/nuxt.ts +++ b/packages/schema/src/types/nuxt.ts @@ -59,6 +59,7 @@ export interface Nuxt { // Private fields. _version: string _ignore?: Ignore + _ignorePatterns?: string[] /** The resolved Nuxt configuration. */ options: NuxtOptions diff --git a/test/basic.test.ts b/test/basic.test.ts index dcdd42ab5a..ec0b6ab1be 100644 --- a/test/basic.test.ts +++ b/test/basic.test.ts @@ -894,6 +894,14 @@ describe('ignore list', () => { const html = await $fetch('/ignore/composables') expect(html).toContain('was import ignored: true') }) + it('should ignore scanned nitro handlers in .nuxtignore', async () => { + const html = await $fetch('/ignore/scanned') + expect(html).not.toContain('this should be ignored') + }) + it.skipIf(isDev())('should ignore public assets in .nuxtignore', async () => { + const html = await $fetch('/ignore/public-asset') + expect(html).not.toContain('this should be ignored') + }) }) describe('server tree shaking', () => { diff --git a/test/fixtures/basic/.nuxtignore b/test/fixtures/basic/.nuxtignore index 03aa617801..59e57a9454 100644 --- a/test/fixtures/basic/.nuxtignore +++ b/test/fixtures/basic/.nuxtignore @@ -1 +1,3 @@ composables/ignored.* +**/ignore/public-asset +server/routes/ignore/scanned.ts diff --git a/test/fixtures/basic/public/ignore/public-asset b/test/fixtures/basic/public/ignore/public-asset new file mode 100644 index 0000000000..9a0adbcc4b --- /dev/null +++ b/test/fixtures/basic/public/ignore/public-asset @@ -0,0 +1 @@ +this should be ignored diff --git a/test/fixtures/basic/server/routes/ignore/scanned.ts b/test/fixtures/basic/server/routes/ignore/scanned.ts new file mode 100644 index 0000000000..8b4f8b7d3b --- /dev/null +++ b/test/fixtures/basic/server/routes/ignore/scanned.ts @@ -0,0 +1,3 @@ +export default defineEventHandler(() => { + return 'this should be ignored' +})