Skip to content
Open
36 changes: 36 additions & 0 deletions packages/wxt/e2e/tests/__snapshots__/auto-imports.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,15 @@ export default {
"
`;

exports[`Auto Imports > eslint config > "enabled: 9" should output a flat config file compatible with ESLint >=9 2`] = `
".wxt/eslint-auto-imports.d.mts
----------------------------------------
import type { ConfigObject } from "@eslint/core";
declare const config: ConfigObject;
export default config;
"
`;

exports[`Auto Imports > eslint config > "enabled: auto" should output a JSON config file compatible with ESLint of package.json 1`] = `
".wxt/eslint-auto-imports.mjs
----------------------------------------
Expand Down Expand Up @@ -182,6 +191,15 @@ export default {
"
`;

exports[`Auto Imports > eslint config > "enabled: auto" should output a JSON config file compatible with ESLint of package.json 2`] = `
".wxt/eslint-auto-imports.d.mts
----------------------------------------
import type { ConfigObject } from "@eslint/core";
declare const config: ConfigObject;
export default config;
"
`;

exports[`Auto Imports > eslint config > "enabled: true" should output a JSON config file compatible with ESLint of package.json 1`] = `
".wxt/eslint-auto-imports.mjs
----------------------------------------
Expand Down Expand Up @@ -245,6 +263,15 @@ export default {
"
`;

exports[`Auto Imports > eslint config > "enabled: true" should output a JSON config file compatible with ESLint of package.json 2`] = `
".wxt/eslint-auto-imports.d.mts
----------------------------------------
import type { ConfigObject } from "@eslint/core";
declare const config: ConfigObject;
export default config;
"
`;

exports[`Auto Imports > eslint config > should allow customizing the output 1`] = `
"example.json
----------------------------------------
Expand Down Expand Up @@ -307,3 +334,12 @@ export default {
};
"
`;

exports[`Auto Imports > eslint config > should allow customizing the output 2`] = `
"example.d.ts
----------------------------------------
import type { ConfigObject } from "@eslint/core";
declare const config: ConfigObject;
export default config;
"
`;
7 changes: 7 additions & 0 deletions packages/wxt/e2e/tests/auto-imports.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,9 @@ describe('Auto Imports', () => {
expect(
await project.serializeFile('.wxt/eslint-auto-imports.mjs'),
).toMatchSnapshot();
expect(
await project.serializeFile('.wxt/eslint-auto-imports.d.mts'),
).toMatchSnapshot();
},
);

Expand Down Expand Up @@ -270,6 +273,9 @@ describe('Auto Imports', () => {
expect(
await project.serializeFile('.wxt/eslint-auto-imports.mjs'),
).toMatchSnapshot();
expect(
await project.serializeFile('.wxt/eslint-auto-imports.d.mts'),
).toMatchSnapshot();
});

it('"enabled: false" should NOT output an ESLint config file', async () => {
Expand Down Expand Up @@ -307,6 +313,7 @@ describe('Auto Imports', () => {
});

expect(await project.serializeFile('example.json')).toMatchSnapshot();
expect(await project.serializeFile('example.d.ts')).toMatchSnapshot();
});

describe('Actual linting results', () => {
Expand Down
50 changes: 34 additions & 16 deletions packages/wxt/src/builtin-modules/unimport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import type {
WxtResolvedUnimportOptions,
EslintConfigVersion,
} from '../types';
import { type Unimport, createUnimport, toExports } from 'unimport';
import { createUnimport, toExports, type Unimport } from 'unimport';
import UnimportPlugin from 'unimport/unplugin';
import { extname } from 'node:path';

export default defineWxtModule({
name: 'wxt:built-in:unimport',
Expand Down Expand Up @@ -52,14 +53,13 @@ export default defineWxtModule({

if (!wxt.config.imports.eslintrc.enabled) 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
Expand Down Expand Up @@ -106,7 +106,7 @@ async function getEslintConfigEntry(
unimport: Unimport,
configVersion: EslintConfigVersion,
options: WxtResolvedUnimportOptions,
): Promise<WxtDirFileEntry> {
): Promise<WxtDirFileEntry[]> {
const globals = (await unimport.getImports())
.map((i) => i.as ?? i.name)
.filter(Boolean)
Expand All @@ -123,18 +123,20 @@ async function getEslintConfigEntry(
export function getEslint8ConfigEntry(
options: WxtResolvedUnimportOptions,
globals: Record<string, EslintGlobalsPropValue>,
): WxtDirFileEntry {
return {
path: options.eslintrc.filePath,
text: JSON.stringify({ globals }, null, 2) + '\n',
};
): WxtDirFileEntry[] {
return [
{
path: options.eslintrc.filePath,
text: JSON.stringify({ globals }, null, 2) + '\n',
},
];
}

export function getEslint9ConfigEntry(
options: WxtResolvedUnimportOptions,
globals: Record<string, EslintGlobalsPropValue>,
): WxtDirFileEntry {
return {
): WxtDirFileEntry[] {
const javaScriptFileEntry: WxtDirFileEntry = {
path: options.eslintrc.filePath,
text: `const globals = ${JSON.stringify(globals, null, 2)}

Expand All @@ -148,4 +150,20 @@ export default {
};
`,
};

const ext = extname(options.eslintrc.filePath);
const declarationExt =
ext === '.mjs' ? '.d.mts' : ext === '.cjs' ? '.d.cts' : '.d.ts';
const typeScriptFilePath =
options.eslintrc.filePath.slice(0, -ext.length) + declarationExt;

const typeScriptFileEntry: WxtDirFileEntry = {
path: typeScriptFilePath,
text: `import type { ConfigObject } from "@eslint/core";
declare const config: ConfigObject;
export default config;
`,
};

return [javaScriptFileEntry, typeScriptFileEntry];
}
Loading