diff --git a/src/core/options.ts b/src/core/options.ts index 2c3939dc..fa4b1ddb 100644 --- a/src/core/options.ts +++ b/src/core/options.ts @@ -4,7 +4,7 @@ import { slash, toArray } from '@antfu/utils' import { getPackageInfoSync, isPackageExists } from 'local-pkg' import { detectTypeImports } from './type-imports/detect' -export const defaultOptions: Omit, 'include' | 'exclude' | 'excludeNames' | 'transformer' | 'globs' | 'directives' | 'types' | 'version'> = { +export const defaultOptions: Omit, 'include' | 'exclude' | 'excludeNames' | 'transformer' | 'globs' | 'globsExclude' | 'directives' | 'types' | 'version'> = { dirs: 'src/components', extensions: 'vue', deep: true, @@ -17,7 +17,6 @@ export const defaultOptions: Omit, 'include' | 'exclude' | 'ex transformerUserResolveFunctions: true, resolvers: [], - globsExclude: [], importPathTransform: v => v, @@ -30,7 +29,7 @@ function normalizeResolvers(resolvers: (ComponentResolver | ComponentResolver[]) function resolveGlobsExclude(root: string, glob: string) { const excludeReg = /^!/ - return `${excludeReg.test(glob) ? '!' : ''}${resolve(root, glob.replace(excludeReg, ''))}` + return slash(`${excludeReg.test(glob) ? '!' : ''}${resolve(root, glob.replace(excludeReg, ''))}`) } export function resolveOptions(options: Options, root: string): ResolvedOptions { @@ -39,7 +38,8 @@ export function resolveOptions(options: Options, root: string): ResolvedOptions resolved.extensions = toArray(resolved.extensions) if (resolved.globs) { - resolved.globs = toArray(resolved.globs).map((glob: string) => slash(resolveGlobsExclude(root, glob))) + resolved.globs = toArray(resolved.globs) + .map(glob => resolveGlobsExclude(root, glob)) resolved.resolvedDirs = [] } else { @@ -48,17 +48,38 @@ export function resolveOptions(options: Options, root: string): ResolvedOptions : `{${resolved.extensions.join(',')}}` resolved.dirs = toArray(resolved.dirs) - resolved.resolvedDirs = resolved.dirs.map(i => slash(resolveGlobsExclude(root, i))) - resolved.globs = resolved.resolvedDirs.map(i => resolved.deep - ? slash(join(i, `**/*.${extsGlob}`)) - : slash(join(i, `*.${extsGlob}`)), - ) + const globs = resolved.dirs.map(i => resolveGlobsExclude(root, i)) + + resolved.resolvedDirs = globs.filter(i => !i.startsWith('!')) + resolved.globs = globs.map((i) => { + let prefix = '' + if (i.startsWith('!')) { + prefix = '!' + i = i.slice(1) + } + return resolved.deep + ? prefix + slash(join(i, `**/*.${extsGlob}`)) + : prefix + slash(join(i, `*.${extsGlob}`)) + }) if (!resolved.extensions.length) throw new Error('[unplugin-vue-components] `extensions` option is required to search for components') } + if (!resolved.globsExclude) + resolved.globsExclude = [`**/node_modules/**`] + resolved.globsExclude = toArray(resolved.globsExclude || []) + .map(i => resolveGlobsExclude(root, i)) + + // Move negated globs to globsExclude + resolved.globs = resolved.globs.filter((i) => { + if (!i.startsWith('!')) + return true + resolved.globsExclude.push(i.slice(1)) + return false + }) + resolved.dts = !resolved.dts ? false : resolve( diff --git a/src/types.ts b/src/types.ts index f16133a7..a7010bb4 100644 --- a/src/types.ts +++ b/src/types.ts @@ -98,7 +98,7 @@ export interface Options { /** * Negated glob patterns to exclude files from being detected as components. * - * @default [] + * @default ['/**\/node_modules/**'] */ globsExclude?: string | string[] @@ -209,6 +209,7 @@ export type ResolvedOptions = Omit< dirs: string[] resolvedDirs: string[] globs: string[] + globsExclude: string[] dts: string | false root: string } diff --git a/test/search.test.ts b/test/search.test.ts index e48bec4d..3277da05 100644 --- a/test/search.test.ts +++ b/test/search.test.ts @@ -1,5 +1,5 @@ import { relative, resolve } from 'pathe' -import { describe, expect, it } from 'vitest' +import { describe, expect, it, onTestFailed } from 'vitest' import { Context } from '../src/core/context' const root = resolve(__dirname, '../examples/vite-vue3') @@ -64,10 +64,18 @@ describe('search', () => { '!src/components/book', ], }) + + onTestFailed(() => { + console.error('resolved options') + console.error(ctx.options) + }) + ctx.setRoot(root) ctx.searchGlob() - expect(cleanup(ctx.componentNameMap).map(i => i.as)).not.toEqual(expect.arrayContaining(['Book'])) + expect(cleanup(ctx.componentNameMap).map(i => i.as)) + .not + .contain('Book') }) it('should excludeNames', () => { diff --git a/vitest.config.ts b/vitest.config.ts index 637aa94f..93c91c41 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -2,10 +2,12 @@ import { defineConfig } from 'vite' export default defineConfig({ test: { - deps: { - inline: [ - '@babel/types', - ], + server: { + deps: { + inline: [ + '@babel/types', + ], + }, }, }, })