Skip to content

Commit 30810fa

Browse files
committed
feat: divide in legacy/nonlegacy, allows eslint 10
1 parent 118248c commit 30810fa

File tree

4 files changed

+76
-71
lines changed

4 files changed

+76
-71
lines changed

packages/wxt/src/builtin-modules/unimport.ts

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import { addViteConfig, defineWxtModule } from '../modules';
22
import type {
33
EslintGlobalsPropValue,
4-
ResolvedEslintrc8,
5-
ResolvedEslintrc9,
6-
ResolvedEslintrcEnabled,
4+
ResolvedEslintrc,
5+
ResolvedEslintrcLegacy,
76
Wxt,
87
WxtDirFileEntry,
98
WxtModule,
@@ -51,7 +50,7 @@ export default defineWxtModule({
5150
// Only create global types when user has enabled auto-imports
5251
entries.push(await getImportsDeclarationEntry(unimport));
5352

54-
if (wxt.config.imports.eslintrc.enabled === false) return;
53+
if (!wxt.config.imports.eslintrc) return;
5554

5655
// Only generate ESLint config if that feature is enabled
5756
const eslintConfigEntries = await getEslintConfigEntries(
@@ -104,7 +103,7 @@ async function getImportsModuleEntry(
104103

105104
async function getEslintConfigEntries(
106105
unimport: Unimport,
107-
eslintrc: ResolvedEslintrcEnabled,
106+
eslintrc: ResolvedEslintrc | ResolvedEslintrcLegacy,
108107
): Promise<WxtDirFileEntry[]> {
109108
const globals = (await unimport.getImports())
110109
.map((i) => i.as ?? i.name)
@@ -115,15 +114,15 @@ async function getEslintConfigEntries(
115114
return globals;
116115
}, {});
117116

118-
if (eslintrc.enabled === 9) {
119-
return getEslint9ConfigEntry(eslintrc, globals);
117+
if (eslintrc.legacy) {
118+
return [getEslintLegacyConfigEntry(eslintrc, globals)];
120119
} else {
121-
return [getEslint8ConfigEntry(eslintrc, globals)];
120+
return getEslintConfigEntry(eslintrc, globals);
122121
}
123122
}
124123

125-
export function getEslint8ConfigEntry(
126-
eslintrc: ResolvedEslintrc8,
124+
export function getEslintLegacyConfigEntry(
125+
eslintrc: ResolvedEslintrcLegacy,
127126
globals: Record<string, EslintGlobalsPropValue>,
128127
): WxtDirFileEntry {
129128
return {
@@ -132,8 +131,8 @@ export function getEslint8ConfigEntry(
132131
};
133132
}
134133

135-
export function getEslint9ConfigEntry(
136-
eslintrc: ResolvedEslintrc9,
134+
export function getEslintConfigEntry(
135+
eslintrc: ResolvedEslintrc,
137136
globals: Record<string, EslintGlobalsPropValue>,
138137
): WxtDirFileEntry[] {
139138
const jsFileEntry: WxtDirFileEntry = {

packages/wxt/src/core/resolve-config.ts

Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import {
1414
WxtModule,
1515
WxtModuleWithMetadata,
1616
ResolvedEslintrc,
17+
ResolvedEslintrcLegacy,
18+
Eslintrc,
1719
} from '../types';
1820
import path from 'node:path';
1921
import { createFsCache } from './utils/cache';
@@ -491,54 +493,64 @@ async function getUnimportOptions(
491493
disabled,
492494
};
493495

494-
return defu<WxtResolvedUnimportOptions, [WxtResolvedUnimportOptions]>(
495-
config.imports ?? {},
496-
defaultOptions,
497-
);
496+
const importsCopy = {
497+
...(config.imports || {}),
498+
eslintrc: undefined,
499+
};
500+
501+
// @ts-expect-error merging objects with different types may create unexpected behavior
502+
return defu(importsCopy, defaultOptions);
498503
}
499504

500505
async function getUnimportEslintOptions(
501506
wxtDir: string,
502507
options: InlineConfig['imports'],
503-
): Promise<ResolvedEslintrc> {
504-
const inlineEnabled =
505-
options === false ? false : (options?.eslintrc?.enabled ?? 'auto');
506-
507-
let enabled: ResolvedEslintrc['enabled'];
508-
switch (inlineEnabled) {
509-
case 'auto':
510-
const version = await getEslintVersion();
511-
let major = parseInt(version[0]);
512-
if (isNaN(major)) enabled = false;
513-
if (major <= 8) enabled = 8;
514-
else if (major >= 9) enabled = 9;
515-
// NaN
516-
else enabled = false;
517-
break;
518-
case true:
519-
enabled = 8;
520-
break;
521-
default:
522-
enabled = inlineEnabled;
523-
}
508+
): Promise<ResolvedEslintrc | ResolvedEslintrcLegacy | undefined> {
509+
if (options === false) return undefined;
524510

525-
if (enabled === false) {
526-
return { enabled: false };
527-
}
511+
const enabled = options?.eslintrc?.enabled;
512+
if (enabled === false) return undefined;
528513

529-
if (enabled === 9) {
530-
return {
531-
enabled: 9,
532-
filePath: path.resolve(wxtDir, 'eslint-auto-imports.mjs'),
533-
definitionPath: path.resolve(wxtDir, 'eslint-auto-imports.d.mts'),
534-
globalsPropValue: true,
535-
};
514+
const isLegacy = enabled === true || enabled === 8;
515+
if (isLegacy) return getEslintLegacyConfig(wxtDir, options.eslintrc);
516+
if (enabled === 9) return getEslintConfig(wxtDir, options.eslintrc);
517+
518+
// Auto-detect ESLint version
519+
520+
const version = await getEslintVersion();
521+
const major = parseInt(version[0]);
522+
523+
if (Number.isNaN(major)) return undefined;
524+
525+
if (major >= 9) {
526+
return getEslintConfig(wxtDir, options.eslintrc);
527+
} else {
528+
return getEslintLegacyConfig(wxtDir, options.eslintrc);
536529
}
530+
}
537531

532+
function getEslintConfig(
533+
wxtDir: string,
534+
eslintrc: Eslintrc | undefined,
535+
): ResolvedEslintrc {
536+
return {
537+
legacy: false,
538+
filePath:
539+
eslintrc?.filePath || path.resolve(wxtDir, 'eslint-auto-imports.mjs'),
540+
definitionPath: path.resolve(wxtDir, 'eslint-auto-imports.d.mts'),
541+
globalsPropValue: eslintrc?.globalsPropValue ?? true,
542+
};
543+
}
544+
545+
function getEslintLegacyConfig(
546+
wxtDir: string,
547+
eslintrc: Eslintrc | undefined,
548+
): ResolvedEslintrcLegacy {
538549
return {
539-
enabled,
540-
filePath: path.resolve(wxtDir, 'eslintrc-auto-import.json'),
541-
globalsPropValue: true,
550+
legacy: true,
551+
filePath:
552+
eslintrc?.filePath || path.resolve(wxtDir, 'eslintrc-auto-import.json'),
553+
globalsPropValue: eslintrc?.globalsPropValue ?? true,
542554
};
543555
}
544556

packages/wxt/src/core/utils/testing/fake-objects.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ export const fakeResolvedConfig = fakeObjectCreator<ResolvedConfig>(() => {
233233
const manifestVersion = faker.helpers.arrayElement([2, 3] as const);
234234
const mode = faker.helpers.arrayElement(['development', 'production']);
235235

236-
return {
236+
const config: ResolvedConfig = {
237237
browser,
238238
targetBrowsers: [],
239239
command,
@@ -246,7 +246,7 @@ export const fakeResolvedConfig = fakeObjectCreator<ResolvedConfig>(() => {
246246
imports: {
247247
disabled: faker.datatype.boolean(),
248248
eslintrc: {
249-
enabled: faker.helpers.arrayElement([false, 8, 9]),
249+
legacy: faker.datatype.boolean(),
250250
filePath: fakeFile(),
251251
definitionPath: fakeFile(),
252252
globalsPropValue: faker.helpers.arrayElement([
@@ -256,7 +256,7 @@ export const fakeResolvedConfig = fakeObjectCreator<ResolvedConfig>(() => {
256256
'readonly',
257257
'writable',
258258
'writeable',
259-
] as const),
259+
]),
260260
},
261261
},
262262
logger: mock(),
@@ -307,6 +307,8 @@ export const fakeResolvedConfig = fakeObjectCreator<ResolvedConfig>(() => {
307307
vite: () => ({}),
308308
plugins: [],
309309
};
310+
311+
return config;
310312
});
311313

312314
export const fakeWxt = fakeObjectCreator<Wxt>(() => ({

packages/wxt/src/types.ts

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,31 +1448,21 @@ export interface Eslintrc {
14481448
globalsPropValue?: EslintGlobalsPropValue;
14491449
}
14501450

1451-
interface ResolvedEslintrcBase {
1451+
export interface ResolvedEslintrcLegacy {
1452+
legacy: true;
14521453
/** Absolute path */
14531454
filePath: string;
14541455
globalsPropValue: EslintGlobalsPropValue;
14551456
}
14561457

1457-
export interface ResolvedEslintrc8 extends ResolvedEslintrcBase {
1458-
enabled: 8;
1459-
}
1460-
1461-
export interface ResolvedEslintrc9 extends ResolvedEslintrcBase {
1462-
enabled: 9;
1458+
export interface ResolvedEslintrc {
1459+
legacy: false;
1460+
/** Absolute path */
1461+
filePath: string;
14631462
definitionPath: string;
1463+
globalsPropValue: EslintGlobalsPropValue;
14641464
}
14651465

1466-
interface ResolvedEslintrcDisabled {
1467-
/** False if disabled, otherwise the major version of ESLint installed */
1468-
enabled: false;
1469-
}
1470-
1471-
export type ResolvedEslintrcEnabled = ResolvedEslintrc8 | ResolvedEslintrc9;
1472-
export type ResolvedEslintrc =
1473-
| ResolvedEslintrcDisabled
1474-
| ResolvedEslintrcEnabled;
1475-
14761466
export type WxtUnimportOptions = Partial<UnimportOptions> & {
14771467
/**
14781468
* When using ESLint, auto-imported variables are linted as "undeclared
@@ -1491,7 +1481,9 @@ export type WxtResolvedUnimportOptions = Partial<UnimportOptions> & {
14911481
* You don't need to check this value before modifying the auto-import options. Even if `disabled` is `true`, there's no harm in adding imports to the config - they'll just be ignored.
14921482
*/
14931483
disabled: boolean;
1494-
eslintrc: ResolvedEslintrc;
1484+
1485+
/** undefined if disabled, otherwise the major version of ESLint installed */
1486+
eslintrc: ResolvedEslintrc | ResolvedEslintrcLegacy | undefined;
14951487
};
14961488

14971489
/**

0 commit comments

Comments
 (0)