From 97736545764ea71e83aa9e76ba3041e916434990 Mon Sep 17 00:00:00 2001 From: bluwy Date: Mon, 20 Apr 2026 13:45:17 +0800 Subject: [PATCH 01/10] refactor: enable `dot-notation` --- eslint.config.js | 1 - packages/vite/src/node/plugins/asset.ts | 8 ++++---- packages/vite/src/node/plugins/html.ts | 4 ++-- packages/vite/src/node/server/hmr.ts | 2 +- packages/vite/src/node/server/index.ts | 2 +- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index 50da4a14811a90..6f373522b5d2cf 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -157,7 +157,6 @@ export default defineConfig( '@typescript-eslint/prefer-function-type': 'off', // disable typecheck-specific rules (but worth revisiting again) '@typescript-eslint/await-thenable': 'off', - '@typescript-eslint/dot-notation': 'off', '@typescript-eslint/no-base-to-string': 'off', '@typescript-eslint/no-duplicate-type-constituents': 'off', '@typescript-eslint/no-implied-eval': 'off', diff --git a/packages/vite/src/node/plugins/asset.ts b/packages/vite/src/node/plugins/asset.ts index a3e4761997cc5c..102e1c3125d2a3 100644 --- a/packages/vite/src/node/plugins/asset.ts +++ b/packages/vite/src/node/plugins/asset.ts @@ -64,13 +64,13 @@ export function registerCustomMime(): void { // https://github.com/lukeed/mrmime/issues/3 // instead of `image/vnd.microsoft.icon` which is registered on IANA Media Types DB // image/x-icon should be used instead for better compatibility (https://github.com/h5bp/html5-boilerplate/issues/219) - mrmime.mimes['ico'] = 'image/x-icon' + mrmime.mimes.ico = 'image/x-icon' // https://mimesniff.spec.whatwg.org/#matching-an-image-type-pattern - mrmime.mimes['cur'] = 'image/x-icon' + mrmime.mimes.cur = 'image/x-icon' // https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Containers#flac - mrmime.mimes['flac'] = 'audio/flac' + mrmime.mimes.flac = 'audio/flac' // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types - mrmime.mimes['eot'] = 'application/vnd.ms-fontobject' + mrmime.mimes.eot = 'application/vnd.ms-fontobject' } export function renderAssetUrlInJS( diff --git a/packages/vite/src/node/plugins/html.ts b/packages/vite/src/node/plugins/html.ts index 938f60163a0b35..dd05ba0175ba1d 100644 --- a/packages/vite/src/node/plugins/html.ts +++ b/packages/vite/src/node/plugins/html.ts @@ -239,7 +239,7 @@ export function getScriptInfo(node: DefaultTreeAdapterMap['element']): { if (p.name === 'src') { if (!src) { src = p - srcSourceCodeLocation = node.sourceCodeLocation?.attrs!['src'] + srcSourceCodeLocation = node.sourceCodeLocation?.attrs!.src } } else if (p.name === 'type' && p.value === 'module') { isModule = true @@ -1085,7 +1085,7 @@ export function findNeedTransformStyleAttribute( (prop.value.includes('url(') || prop.value.includes('image-set(')), ) if (!attr) return undefined - const location = node.sourceCodeLocation?.attrs?.['style'] + const location = node.sourceCodeLocation?.attrs?.style return { attr, location } } diff --git a/packages/vite/src/node/server/hmr.ts b/packages/vite/src/node/server/hmr.ts index 2298047efaf23a..32d8f36d5b6801 100644 --- a/packages/vite/src/node/server/hmr.ts +++ b/packages/vite/src/node/server/hmr.ts @@ -348,7 +348,7 @@ export function getSortedPluginsByHotUpdateHook( normal = 0, post = 0 for (const plugin of plugins) { - const hook = plugin['hotUpdate'] ?? plugin['handleHotUpdate'] + const hook = plugin.hotUpdate ?? plugin.handleHotUpdate if (hook) { if (typeof hook === 'object') { if (hook.order === 'pre') { diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index dc0b272bf01c70..a7318e3fd04d7e 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -978,7 +978,7 @@ export async function _createServer( // ping request handler // Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...` middlewares.use(function viteHMRPingMiddleware(req, res, next) { - if (req.headers['accept'] === 'text/x-vite-ping') { + if (req.headers.accept === 'text/x-vite-ping') { res.writeHead(204).end() } else { next() From 561d7cf06429a3a4d5192bd91f953b5076d0f8e9 Mon Sep 17 00:00:00 2001 From: bluwy Date: Mon, 20 Apr 2026 13:58:54 +0800 Subject: [PATCH 02/10] refactor: handle `no-duplicate-type-constituents` but keep off --- packages/vite/src/node/server/pluginContainer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vite/src/node/server/pluginContainer.ts b/packages/vite/src/node/server/pluginContainer.ts index 73404b4743e68f..8836f252025654 100644 --- a/packages/vite/src/node/server/pluginContainer.ts +++ b/packages/vite/src/node/server/pluginContainer.ts @@ -918,7 +918,7 @@ class PluginContext private _formatLog( e: string | E, - position?: number | { column: number; line: number } | undefined, + position?: number | { column: number; line: number }, ): E { const err = (typeof e === 'string' ? new Error(e) : e) as E if (err.pluginCode) { From 18dc1c5fc38f8cae41ecd6c15c3753a0f06f171b Mon Sep 17 00:00:00 2001 From: bluwy Date: Mon, 20 Apr 2026 14:07:54 +0800 Subject: [PATCH 03/10] chore: add comments for rules so far --- eslint.config.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index 6f373522b5d2cf..b786189ca8178b 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -155,11 +155,10 @@ export default defineConfig( '@typescript-eslint/consistent-type-definitions': 'off', '@typescript-eslint/prefer-for-of': 'off', '@typescript-eslint/prefer-function-type': 'off', - // disable typecheck-specific rules (but worth revisiting again) - '@typescript-eslint/await-thenable': 'off', - '@typescript-eslint/no-base-to-string': 'off', - '@typescript-eslint/no-duplicate-type-constituents': 'off', - '@typescript-eslint/no-implied-eval': 'off', + // disable typecheck-specific rules + '@typescript-eslint/await-thenable': 'off', // does not handle `void | Promise` well + '@typescript-eslint/no-base-to-string': 'off', // does not matter for us + '@typescript-eslint/no-implied-eval': 'off', // we intentionally use `Function()` '@typescript-eslint/no-floating-promises': 'off', '@typescript-eslint/no-misused-promises': 'off', '@typescript-eslint/no-redundant-type-constituents': 'off', @@ -375,6 +374,13 @@ export default defineConfig( '@typescript-eslint/ban-ts-comment': 'off', }, }, + { + name: 'disables/test-dts', + files: ['**/__tests_dts__/**/*.?([cm])[jt]s?(x)'], + rules: { + '@typescript-eslint/no-duplicate-type-constituents': 'off', + }, + }, { name: 'disables/typechecking', files: [ From 4c9b70fe4c085a53bd566c53806da258aa140137 Mon Sep 17 00:00:00 2001 From: bluwy Date: Mon, 20 Apr 2026 14:16:34 +0800 Subject: [PATCH 04/10] refactor: handle `no-redundant-type-constituents` but keep off --- eslint.config.js | 3 ++- packages/vite/src/module-runner/evaluatedModules.ts | 2 +- packages/vite/src/node/plugins/css.ts | 2 +- packages/vite/src/node/utils.ts | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index b786189ca8178b..b63b299ab4d850 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -161,7 +161,7 @@ export default defineConfig( '@typescript-eslint/no-implied-eval': 'off', // we intentionally use `Function()` '@typescript-eslint/no-floating-promises': 'off', '@typescript-eslint/no-misused-promises': 'off', - '@typescript-eslint/no-redundant-type-constituents': 'off', + '@typescript-eslint/no-redundant-type-constituents': 'off', // hard to handle some cases '@typescript-eslint/no-unnecessary-type-assertion': 'off', '@typescript-eslint/no-unsafe-argument': 'off', '@typescript-eslint/no-unsafe-assignment': 'off', @@ -378,6 +378,7 @@ export default defineConfig( name: 'disables/test-dts', files: ['**/__tests_dts__/**/*.?([cm])[jt]s?(x)'], rules: { + // disable typecheck-specific rules '@typescript-eslint/no-duplicate-type-constituents': 'off', }, }, diff --git a/packages/vite/src/module-runner/evaluatedModules.ts b/packages/vite/src/module-runner/evaluatedModules.ts index fdad30dcf832df..934073b1c9a104 100644 --- a/packages/vite/src/module-runner/evaluatedModules.ts +++ b/packages/vite/src/module-runner/evaluatedModules.ts @@ -14,7 +14,7 @@ export class EvaluatedModuleNode { public evaluated = false public meta: ResolvedResult | undefined public promise: Promise | undefined - public exports: any | undefined + public exports: any public file: string public map: DecodedMap | undefined diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index 596caaef46e28f..3188e3a7c42c00 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -2467,7 +2467,7 @@ async function loadSss(root: string): Promise { return cachedSss } -declare const window: unknown | undefined +declare const window: unknown declare const location: { href: string } | undefined // in unix, scss might append `location.href` in environments that shim `location` diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index 5db2be5fcb9faf..1f9fa309696595 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -62,7 +62,7 @@ export const createFilter = _createFilter as ( include?: FilterPattern, exclude?: FilterPattern, options?: { resolve?: string | false | null }, -) => (id: string | unknown) => boolean +) => (id: unknown) => boolean export { withFilter } from 'rolldown/filter' From 2471d6227c947273e16d2d547d773298e5a0df9a Mon Sep 17 00:00:00 2001 From: bluwy Date: Mon, 20 Apr 2026 18:17:58 +0800 Subject: [PATCH 05/10] refactor: enable `no-unsafe-enum-comparison` --- eslint.config.js | 1 - packages/vite/rolldown.config.ts | 7 +++++-- packages/vite/src/node/plugins/html.ts | 15 ++++++++------- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index b63b299ab4d850..3a0b3e4af83a05 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -166,7 +166,6 @@ export default defineConfig( '@typescript-eslint/no-unsafe-argument': 'off', '@typescript-eslint/no-unsafe-assignment': 'off', '@typescript-eslint/no-unsafe-call': 'off', - '@typescript-eslint/no-unsafe-enum-comparison': 'off', '@typescript-eslint/no-unsafe-member-access': 'off', '@typescript-eslint/no-unsafe-return': 'off', '@typescript-eslint/non-nullable-type-assertion-style': 'off', diff --git a/packages/vite/rolldown.config.ts b/packages/vite/rolldown.config.ts index 5e26173dc7b722..0255d8c544c856 100644 --- a/packages/vite/rolldown.config.ts +++ b/packages/vite/rolldown.config.ts @@ -3,7 +3,7 @@ import path from 'node:path' import MagicString from 'magic-string' import type { Plugin } from 'rolldown' import { defineConfig } from 'rolldown' -import { init, parse } from 'es-module-lexer' +import { ImportType, init, parse } from 'es-module-lexer' import licensePlugin from './rollupLicensePlugin' // eslint-disable-next-line n/no-unsupported-features/node-builtins @@ -321,7 +321,10 @@ function buildTimeImportMetaUrlPlugin(): Plugin { const s = new MagicString(code) const [imports] = parse(code) for (const { t, ss, se } of imports) { - if (t === 3 && code.slice(se, se + 4) === '.url') { + if ( + t === ImportType.ImportMeta && + code.slice(se, se + 4) === '.url' + ) { // ignore import.meta.url with /** #__KEEP__ */ comment if (keepCommentRE.test(code.slice(0, ss))) { keepCommentRE.lastIndex = 0 diff --git a/packages/vite/src/node/plugins/html.ts b/packages/vite/src/node/plugins/html.ts index dd05ba0175ba1d..52def92e4577aa 100644 --- a/packages/vite/src/node/plugins/html.ts +++ b/packages/vite/src/node/plugins/html.ts @@ -206,13 +206,13 @@ export async function traverseHtml( visitor: (node: DefaultTreeAdapterMap['node']) => void, ): Promise { // lazy load compiler - const { parse } = await import('parse5') + const { parse, ErrorCodes } = await import('parse5') const warnings: ParseWarnings = {} const ast = parse(html, { scriptingEnabled: false, // parse inside