Problem
eslint.config.shared.js spreads core ESLint's recommended rules into the base config for **/*.ts and **/*.tsx:
rules: {
...eslint.configs.recommended.rules, // <-- this turns on `no-undef`
...tseslint.configs.recommended.rules,
...
}
That enables core no-undef on TypeScript files. Confirmed via eslint --print-config in src/core:
no-undef: [2, {"typeof": false}]
typescript-eslint explicitly recommends turning no-undef off for TS files: tsc already performs this check with full knowledge of the type system, and the ESLint rule produces false positives on type-only references.
The trap
no-undef currently reports nothing, so it looks harmless. It is silent only as an accident of an unrelated setting:
Setting parserOptions.project causes @typescript-eslint/parser to read lib out of the tsconfig and inject the corresponding DOM/ES globals into ESLint's scope analysis. Those injected globals are what keep no-undef quiet.
Verified:
- Removing
project from src/diagram produces 383 spurious no-undef errors.
- Adding
parserOptions.lib: ['es2020','dom','dom.iterable'] back makes the findings byte-identical to the project run.
So no-undef is load-bearing on parserOptions.project -- a setting that exists for type-aware linting, of which we currently enable exactly zero rules.
Why it matters
This is a landmine for the next person who tries to speed up linting. project is a ~30% wall-clock cost on src/diagram and buys nothing today, so dropping it is the obvious optimization -- and it detonates 383 bogus errors that have nothing to do with the change. The failure mode gives no hint that no-undef is the culprit or that lib is the fix.
The hand-maintained globals block in the shared config (window, document, Image, requestAnimationFrame, JSX, ...) is a symptom of the same confusion: it exists to placate no-undef, and it will never be complete.
Fix
Set 'no-undef': 'off' for TS/TSX files in eslint.config.shared.js. tsc already covers it.
Once no-undef is off, the bespoke globals list can likely be pruned too -- worth checking which of the remaining core rules (if any) actually consume it.
Components affected
eslint.config.shared.js
- All consumers:
src/{core,diagram,app,engine,server}/eslint.config.js, website/eslint.config.js
Discovery context
Identified during an audit of eslint.config.shared.js while migrating the repo to TypeScript 7.
Related
This is one of five defects found in the same audit of eslint.config.shared.js:
Problem
eslint.config.shared.jsspreads core ESLint's recommended rules into the base config for**/*.tsand**/*.tsx:That enables core
no-undefon TypeScript files. Confirmed viaeslint --print-configinsrc/core:typescript-eslint explicitly recommends turning
no-undefoff for TS files:tscalready performs this check with full knowledge of the type system, and the ESLint rule produces false positives on type-only references.The trap
no-undefcurrently reports nothing, so it looks harmless. It is silent only as an accident of an unrelated setting:Setting
parserOptions.projectcauses@typescript-eslint/parserto readlibout of the tsconfig and inject the corresponding DOM/ES globals into ESLint's scope analysis. Those injected globals are what keepno-undefquiet.Verified:
projectfromsrc/diagramproduces 383 spuriousno-undeferrors.parserOptions.lib: ['es2020','dom','dom.iterable']back makes the findings byte-identical to theprojectrun.So
no-undefis load-bearing onparserOptions.project-- a setting that exists for type-aware linting, of which we currently enable exactly zero rules.Why it matters
This is a landmine for the next person who tries to speed up linting.
projectis a ~30% wall-clock cost onsrc/diagramand buys nothing today, so dropping it is the obvious optimization -- and it detonates 383 bogus errors that have nothing to do with the change. The failure mode gives no hint thatno-undefis the culprit or thatlibis the fix.The hand-maintained
globalsblock in the shared config (window,document,Image,requestAnimationFrame,JSX, ...) is a symptom of the same confusion: it exists to placateno-undef, and it will never be complete.Fix
Set
'no-undef': 'off'for TS/TSX files ineslint.config.shared.js.tscalready covers it.Once
no-undefis off, the bespokeglobalslist can likely be pruned too -- worth checking which of the remaining core rules (if any) actually consume it.Components affected
eslint.config.shared.jssrc/{core,diagram,app,engine,server}/eslint.config.js,website/eslint.config.jsDiscovery context
Identified during an audit of
eslint.config.shared.jswhile migrating the repo to TypeScript 7.Related
This is one of five defects found in the same audit of
eslint.config.shared.js:projectand trip this)createConfig()