From 913ba1496fa3ce0062057b509d691d0fbbe9e7bc Mon Sep 17 00:00:00 2001 From: fkatsuhiro Date: Wed, 5 Aug 2026 06:43:13 +0900 Subject: [PATCH 1/4] feat(test): auto-import feature --- packages/wxt/e2e/tests/auto-imports.test.ts | 50 +++++++++++++++++ .../internal/__tests__/resolve-config.test.ts | 54 +++++++++++++++++++ 2 files changed, 104 insertions(+) diff --git a/packages/wxt/e2e/tests/auto-imports.test.ts b/packages/wxt/e2e/tests/auto-imports.test.ts index 1c3c5b11c..bfc6d5ec6 100644 --- a/packages/wxt/e2e/tests/auto-imports.test.ts +++ b/packages/wxt/e2e/tests/auto-imports.test.ts @@ -133,6 +133,56 @@ describe('Auto Imports', () => { }); }); + describe('imports: { scan: false }', () => { + it('should not auto-import from the default directories, but should keep preset/library imports', async () => { + const project = new TestProject(); + project.setConfigFileConfig({ + imports: { scan: false }, + }); + project.addFile('entrypoints/popup.html', ``); + project.addFile( + 'utils/time.ts', + `export function startOfDay(date: Date): Date { + throw Error("TODO") + }`, + ); + + await project.prepare(); + + const declaration = await project.serializeFile( + '.wxt/types/imports.d.ts', + ); + expect(declaration).not.toContain('startOfDay'); + expect(declaration).toContain('browser'); + }); + + it('should only auto-import from directories explicitly listed in dirs', async () => { + const project = new TestProject(); + project.setConfigFileConfig({ + imports: { scan: false, dirs: ['helpers'] }, + }); + project.addFile('entrypoints/popup.html', ``); + project.addFile( + 'utils/time.ts', + `export function startOfDay(date: Date): Date { + throw Error("TODO") + }`, + ); + project.addFile( + 'helpers/index.ts', + `export function helperFn(): void {}`, + ); + + await project.prepare(); + + const declaration = await project.serializeFile( + '.wxt/types/imports.d.ts', + ); + expect(declaration).not.toContain('startOfDay'); + expect(declaration).toContain('helperFn'); + }); + }); + describe('imports: false', () => { it('should not generate a imports.d.ts file', async () => { const project = new TestProject(); diff --git a/packages/wxt/src/internal/__tests__/resolve-config.test.ts b/packages/wxt/src/internal/__tests__/resolve-config.test.ts index d91d0d22e..0b9e90f11 100644 --- a/packages/wxt/src/internal/__tests__/resolve-config.test.ts +++ b/packages/wxt/src/internal/__tests__/resolve-config.test.ts @@ -37,4 +37,58 @@ describe('resolveConfig', () => { ); }); }); + + describe('imports.dirs', () => { + const logger = mock(); + + it('should default to the built-in directories', async () => { + const config = await resolveConfig({ logger }, 'build'); + + expect(config.imports.dirs).toEqual([ + 'components', + 'composables', + 'hooks', + 'utils', + ]); + }); + + it('should extend the built-in directories when dirs is set', async () => { + const config = await resolveConfig( + { logger, imports: { dirs: ['some-directory'] } }, + 'build', + ); + + expect(config.imports.dirs).toEqual([ + 'some-directory', + 'components', + 'composables', + 'hooks', + 'utils', + ]); + }); + + it('should clear the built-in directories when scan is false', async () => { + const config = await resolveConfig( + { logger, imports: { scan: false } }, + 'build', + ); + + expect(config.imports.dirs).toEqual([]); + }); + + it('should replace the built-in directories when scan is false and dirs is set', async () => { + const config = await resolveConfig( + { logger, imports: { scan: false, dirs: ['some-directory'] } }, + 'build', + ); + + expect(config.imports.dirs).toEqual(['some-directory']); + }); + + it('should stay empty when imports is disabled', async () => { + const config = await resolveConfig({ logger, imports: false }, 'build'); + + expect(config.imports.dirs).toEqual([]); + }); + }); }); From 17997ed1996c5b2d25fd174c1c1d0679ded6e9aa Mon Sep 17 00:00:00 2001 From: fkatsuhiro Date: Wed, 5 Aug 2026 06:45:30 +0900 Subject: [PATCH 2/4] feat: auto-import overwrite specified directries --- docs/guide/essentials/config/auto-imports.md | 35 ++++++++++++++++++++ packages/wxt/src/internal/resolve-config.ts | 5 ++- packages/wxt/src/types.ts | 21 ++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/docs/guide/essentials/config/auto-imports.md b/docs/guide/essentials/config/auto-imports.md index 9c2a0fdeb..178839877 100644 --- a/docs/guide/essentials/config/auto-imports.md +++ b/docs/guide/essentials/config/auto-imports.md @@ -22,6 +22,41 @@ All named and default exports from files in these directories are available ever To see the complete list of auto-imported APIs, run [`wxt prepare`](/api/cli/wxt-prepare) and look at your project's `.wxt/types/imports-module.d.ts` file. +### Extending Default Directories + +Add additional directories with `imports.dirs`. They're combined with the default directories listed above. + +```ts +export default defineConfig({ + imports: { + dirs: ['lib'], + }, +}); +``` + +### Overriding or Disabling Default Directories + +Set `imports.scan` to `false` to stop WXT from scanning its default directories (`components`, `composables`, `hooks`, and `utils`). Preset/library based imports (like `browser`, `storage`, etc.) are unaffected, so this can be used to keep auto-imports enabled while opting out of directory scanning. + +```ts +export default defineConfig({ + imports: { + scan: false, + }, +}); +``` + +Combine `scan: false` with `dirs` to replace the default directories with your own instead of extending them: + +```ts +export default defineConfig({ + imports: { + scan: false, + dirs: ['lib'], + }, +}); +``` + ## TypeScript For TypeScript and your editor to recognize auto-imported variables, you need to run the [`wxt prepare` command](/api/cli/wxt-prepare). diff --git a/packages/wxt/src/internal/resolve-config.ts b/packages/wxt/src/internal/resolve-config.ts index a1d8d4981..410686d79 100644 --- a/packages/wxt/src/internal/resolve-config.ts +++ b/packages/wxt/src/internal/resolve-config.ts @@ -485,7 +485,10 @@ async function getUnimportOptions( cwd: srcDir, }, eslintrc, - dirs: disabled ? [] : ['components', 'composables', 'hooks', 'utils'], + dirs: + disabled || (config.imports !== false && config.imports?.scan === false) + ? [] + : ['components', 'composables', 'hooks', 'utils'], disabled, }; diff --git a/packages/wxt/src/types.ts b/packages/wxt/src/types.ts index b4e389f87..4fcddb12f 100644 --- a/packages/wxt/src/types.ts +++ b/packages/wxt/src/types.ts @@ -1774,6 +1774,27 @@ export type WxtUnimportOptions = Partial & { * [https://wxt.dev/guide/essentials/config/auto-imports.html#eslint](https://wxt.dev/guide/essentials/config/auto-imports.html#eslint) */ eslintrc?: Eslintrc; + /** + * Set to `false` to stop WXT from scanning its default auto-import + * directories (`components`, `composables`, `hooks`, and `utils`, relative to + * `srcDir`). Preset/library based imports (from `imports` and `presets`) are + * unaffected. + * + * Combine with `dirs` to replace the default directories with your own, + * instead of extending them: + * + * ```ts + * export default defineConfig({ + * imports: { + * scan: false, + * dirs: ['some-directory'], + * }, + * }); + * ``` + * + * @default true + */ + scan?: boolean; }; export type WxtResolvedUnimportOptions = Partial & { From ad0c2ad539004b9e847ea54ad0f0c077ccc9d7be Mon Sep 17 00:00:00 2001 From: Gliches Date: Tue, 27 Oct 2026 11:09:09 +0530 Subject: [PATCH 3/4] Update docs/guide/essentials/config/auto-imports.md --- docs/guide/essentials/config/auto-imports.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/essentials/config/auto-imports.md b/docs/guide/essentials/config/auto-imports.md index 178839877..24df115d5 100644 --- a/docs/guide/essentials/config/auto-imports.md +++ b/docs/guide/essentials/config/auto-imports.md @@ -34,7 +34,7 @@ export default defineConfig({ }); ``` -### Overriding or Disabling Default Directories +## Overriding or Disabling Default Directories Set `imports.scan` to `false` to stop WXT from scanning its default directories (`components`, `composables`, `hooks`, and `utils`). Preset/library based imports (like `browser`, `storage`, etc.) are unaffected, so this can be used to keep auto-imports enabled while opting out of directory scanning. From 5ed5989ac00d27da7ccb962290f9d4a9df349958 Mon Sep 17 00:00:00 2001 From: Gliches Date: Tue, 27 Oct 2026 11:13:25 +0530 Subject: [PATCH 4/4] Update docs/guide/essentials/config/auto-imports.md --- docs/guide/essentials/config/auto-imports.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/essentials/config/auto-imports.md b/docs/guide/essentials/config/auto-imports.md index 24df115d5..a8cd47458 100644 --- a/docs/guide/essentials/config/auto-imports.md +++ b/docs/guide/essentials/config/auto-imports.md @@ -22,7 +22,7 @@ All named and default exports from files in these directories are available ever To see the complete list of auto-imported APIs, run [`wxt prepare`](/api/cli/wxt-prepare) and look at your project's `.wxt/types/imports-module.d.ts` file. -### Extending Default Directories +## Extending Default Directories Add additional directories with `imports.dirs`. They're combined with the default directories listed above.