From b4d1f8c2f0e57163df2f2d86fa530cd1a2cf17cc Mon Sep 17 00:00:00 2001 From: Andrei L <1881266+unrevised6419@users.noreply.github.com> Date: Wed, 17 Dec 2025 17:29:09 +0200 Subject: [PATCH] fix(imports): generate .d.ts file for eslint > 9 auto imports --- packages/wxt-demo/eslint.config.js | 2 +- packages/wxt-demo/wxt.config.ts | 7 ++ packages/wxt/src/builtin-modules/unimport.ts | 45 ++++++++--- pnpm-lock.yaml | 78 ++++++++++++++++++-- 4 files changed, 114 insertions(+), 18 deletions(-) diff --git a/packages/wxt-demo/eslint.config.js b/packages/wxt-demo/eslint.config.js index 0d75cf23b..06f07440b 100644 --- a/packages/wxt-demo/eslint.config.js +++ b/packages/wxt-demo/eslint.config.js @@ -1,4 +1,4 @@ -import autoImports from './.wxt/eslintrc-auto-import.js'; +import autoImports from './.wxt/eslintrc-auto-import.json'; export default [ { diff --git a/packages/wxt-demo/wxt.config.ts b/packages/wxt-demo/wxt.config.ts index e68b93b46..5ff6e335b 100644 --- a/packages/wxt-demo/wxt.config.ts +++ b/packages/wxt-demo/wxt.config.ts @@ -1,5 +1,6 @@ import { defineConfig } from 'wxt'; import { presetUno } from 'unocss'; +import path from 'node:path'; export default defineConfig({ srcDir: 'src', @@ -56,4 +57,10 @@ export default defineConfig({ presets: [presetUno()], }, }, + imports: { + eslintrc: { + enabled: true, + filePath: path.resolve('.wxt/eslintrc-auto-import.json'), + }, + }, }); diff --git a/packages/wxt/src/builtin-modules/unimport.ts b/packages/wxt/src/builtin-modules/unimport.ts index c49bde02c..7577afcc0 100644 --- a/packages/wxt/src/builtin-modules/unimport.ts +++ b/packages/wxt/src/builtin-modules/unimport.ts @@ -1,3 +1,4 @@ +import path from 'node:path'; import { addViteConfig, defineWxtModule } from '../modules'; import type { EslintGlobalsPropValue, @@ -49,16 +50,16 @@ export default defineWxtModule({ // Only create global types when user has enabled auto-imports entries.push(await getImportsDeclarationEntry(unimport)); + // Only generate ESLint config if that feature is enabled if (wxt.config.imports.eslintrc.enabled === false) return; - // Only generate ESLint config if that feature is enabled - entries.push( - await getEslintConfigEntry( - unimport, - wxt.config.imports.eslintrc.enabled, - wxt.config.imports, - ), + const eslintConfigEntries = await getEslintConfigEntry( + unimport, + wxt.config.imports.eslintrc.enabled, + wxt.config.imports, ); + + entries.push(...eslintConfigEntries); }); // Add vite plugin @@ -105,7 +106,7 @@ async function getEslintConfigEntry( unimport: Unimport, version: 8 | 9, options: WxtResolvedUnimportOptions, -): Promise { +): Promise { const globals = (await unimport.getImports()) .map((i) => i.as ?? i.name) .filter(Boolean) @@ -115,7 +116,7 @@ async function getEslintConfigEntry( return globals; }, {}); - if (version <= 8) return getEslint8ConfigEntry(options, globals); + if (version <= 8) return [getEslint8ConfigEntry(options, globals)]; else return getEslint9ConfigEntry(options, globals); } @@ -132,8 +133,8 @@ export function getEslint8ConfigEntry( export function getEslint9ConfigEntry( options: WxtResolvedUnimportOptions, globals: Record, -): WxtDirFileEntry { - return { +): WxtDirFileEntry[] { + const javaScriptFileEntry: WxtDirFileEntry = { path: options.eslintrc.filePath, text: `const globals = ${JSON.stringify(globals, null, 2)} @@ -147,4 +148,26 @@ export default { }; `, }; + + const javaScriptFileDirname = path.dirname(options.eslintrc.filePath); + const javaScriptFileExtension = path.extname(options.eslintrc.filePath); + const javaScriptFileBasename = path.basename( + options.eslintrc.filePath, + javaScriptFileExtension, + ); + + const typeScriptFilePath = path.join( + javaScriptFileDirname, + `${javaScriptFileBasename}.d.ts`, + ); + + const typeScriptFileEntry: WxtDirFileEntry = { + path: typeScriptFilePath, + text: `import type { ConfigObject } from "@eslint/core"; +declare const config: ConfigObject; +export default config; +`, + }; + + return [javaScriptFileEntry, typeScriptFileEntry]; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d71b74cf4..be4f45537 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -182,20 +182,20 @@ importers: specifier: 0.1.32 version: 0.1.32 fs-extra: - specifier: ^11.3.2 + specifier: ^11.3.1 version: 11.3.2 nano-spawn: - specifier: ^1.0.3 + specifier: ^1.0.2 version: 1.0.3 tsx: - specifier: 4.21.0 - version: 4.21.0 + specifier: 4.20.5 + version: 4.20.5 typescript: - specifier: ^5.9.3 + specifier: ^5.9.2 version: 5.9.3 vitest: specifier: ^4.0.16 - version: 4.0.16(@types/node@20.19.13)(happy-dom@20.0.11)(jiti@2.6.1)(sass@1.97.0)(tsx@4.21.0)(yaml@2.8.1) + version: 4.0.16(@types/node@20.19.13)(happy-dom@20.0.11)(jiti@2.6.1)(sass@1.97.0)(tsx@4.20.5)(yaml@2.8.1) packages/i18n: dependencies: @@ -4603,6 +4603,11 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsx@4.20.5: + resolution: {integrity: sha512-+wKjMNU9w/EaQayHXb7WA7ZaHY6hN8WgfvHNQ3t1PnU91/7O8TcTnIhCDYTZwnt8JsO9IBqZ30Ln1r7pPF52Aw==} + engines: {node: '>=18.0.0'} + hasBin: true + tsx@4.21.0: resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} engines: {node: '>=18.0.0'} @@ -9060,6 +9065,13 @@ snapshots: tslib@2.8.1: {} + tsx@4.20.5: + dependencies: + esbuild: 0.25.9 + get-tsconfig: 4.10.1 + optionalDependencies: + fsevents: 2.3.3 + tsx@4.21.0: dependencies: esbuild: 0.27.1 @@ -9318,6 +9330,22 @@ snapshots: fsevents: 2.3.3 sass: 1.97.0 + vite@7.3.0(@types/node@20.19.13)(jiti@2.6.1)(sass@1.97.0)(tsx@4.20.5)(yaml@2.8.1): + dependencies: + esbuild: 0.27.1 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.50.0 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 20.19.13 + fsevents: 2.3.3 + jiti: 2.6.1 + sass: 1.97.0 + tsx: 4.20.5 + yaml: 2.8.1 + vite@7.3.0(@types/node@20.19.13)(jiti@2.6.1)(sass@1.97.0)(tsx@4.21.0)(yaml@2.8.1): dependencies: esbuild: 0.27.1 @@ -9415,6 +9443,44 @@ snapshots: dependencies: vite: 7.3.0(@types/node@20.19.13)(jiti@2.6.1)(sass@1.97.0)(tsx@4.21.0)(yaml@2.8.1) + vitest@4.0.16(@types/node@20.19.13)(happy-dom@20.0.11)(jiti@2.6.1)(sass@1.97.0)(tsx@4.20.5)(yaml@2.8.1): + dependencies: + '@vitest/expect': 4.0.16 + '@vitest/mocker': 4.0.16(vite@7.3.0(@types/node@20.19.13)(jiti@2.6.1)(sass@1.97.0)(tsx@4.21.0)(yaml@2.8.1)) + '@vitest/pretty-format': 4.0.16 + '@vitest/runner': 4.0.16 + '@vitest/snapshot': 4.0.16 + '@vitest/spy': 4.0.16 + '@vitest/utils': 4.0.16 + es-module-lexer: 1.7.0 + expect-type: 1.2.2 + magic-string: 0.30.21 + obug: 2.1.1 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 3.10.0 + tinybench: 2.9.0 + tinyexec: 1.0.2 + tinyglobby: 0.2.15 + tinyrainbow: 3.0.3 + vite: 7.3.0(@types/node@20.19.13)(jiti@2.6.1)(sass@1.97.0)(tsx@4.20.5)(yaml@2.8.1) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 20.19.13 + happy-dom: 20.0.11 + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - yaml + vitest@4.0.16(@types/node@20.19.13)(happy-dom@20.0.11)(jiti@2.6.1)(sass@1.97.0)(tsx@4.21.0)(yaml@2.8.1): dependencies: '@vitest/expect': 4.0.16