Add ESLint with flat config, lint script, and CI enforcement#289
Add ESLint with flat config, lint script, and CI enforcement#289jeremyzilar wants to merge 8 commits into
Conversation
Installs eslint, typescript-eslint, eslint-plugin-react, eslint-plugin-react-hooks, eslint-plugin-react-refresh, and eslint-config-prettier. Adds eslint.config.ts at the repo root with recommended rules for TypeScript and React, with most violations set to warn initially so the codebase can be cleaned up incrementally. Adds npm run lint and lint:fix scripts to package.json and a Lint step to CI_vitest.yml that fails the build on errors. Adds LINTING.md documenting the ruleset and how to run it locally.
Preview DeploymentPreview URL: https://preview-bdms-837-auejgdbofq-uc.a.run.app Note: This preview uses the staging API endpoints. |
Preview DeploymentPreview URL: https://preview-bdms-837-auejgdbofq-uc.a.run.app Note: This preview uses the staging API endpoints. |
- Demote all react-hooks compiler rules (set-state-in-effect, refs, purity, etc) to warn — violations are pre-existing and non-critical at current scale. See react-compiler.md in the-brain for the full decision. - Fix react/jsx-no-comment-textnodes in routes/ocotillo.tsx - Fix react/no-unescaped-entities in GameResults.tsx and TypographyPage.tsx - Replace bare Function types with explicit signatures in utils/Link.tsx - Extract LexiconHeaderButtons as a proper component so useExport is called at component scope, not inside a render function - Fix conditional useRef in MapComponent by always calling useRef and choosing between internal and external ref after - Fix useMemo called after early return in RecentWaterLevelObservations - Fix useLink called inside linkColumn by passing Link as a parameter; callers (SampleList, WellScreenList) now call useLink at component top level - Replace non-breaking spaces with regular spaces in ControlledSelectWithChipsField - Fix split let declaration/assignment in geothermal-data-provider
Preview DeploymentPreview URL: https://preview-bdms-837-auejgdbofq-uc.a.run.app Note: This preview uses the staging API endpoints. |
…ontexts and hooks Moved SupportPanelContext to its own file so AppShell only exports components. Moved useSidebar and SidebarContext to use-sidebar.ts so sidebar.tsx only exports components. Removed unused vars from AppSidebar that belonged to ShellHeader. Updated ReportBugButton to import SupportPanelContext from its new location.
Preview DeploymentPreview URL: https://preview-bdms-837-auejgdbofq-uc.a.run.app Note: This preview uses the staging API endpoints. |
| run: npm ci | ||
|
|
||
| - name: Lint | ||
| run: npm run lint |
There was a problem hiding this comment.
Can linting be its only GitHub workflow? It might be confusing to see the Vite test workflow fail, only to find it's actually a linting error later.
| sx={{ px: 2, py: 2, textAlign: 'center' }} | ||
| > | ||
| No games found for "{term}". | ||
| No games found for "{term}". |
|
@jeremyzilar, where's the completed decision document for the React Compiler located? |
Preview DeploymentPreview URL: https://preview-bdms-837-auejgdbofq-uc.a.run.app Note: This preview uses the staging API endpoints. |
chasetmartin
left a comment
There was a problem hiding this comment.
Nice work, this will be great. I'll resist the urge to include an ESLint meme 😂
What this does
Adds ESLint to OcotilloUI. There was no linting at all before this PR. This is Ticket 1.2 from Epic 1 (Code Health).
What was added
eslint.config.ts— flat config at the repo root, covering TypeScript, React, React Hooks, and Prettier compatibilitynpm run lintandnpm run lint:fixscripts inpackage.jsonLintstep inCI_vitest.ymlthat fails the build on any ESLint errorLINTING.mddocumenting the ruleset and how to run it locally.vscode/settings.json— format on save via Prettier.vscode/extensions.json— recommends the Prettier and ESLint extensions when someone opens the repoRule philosophy
Most violations are set to
warnrather thanerrorso we aren't blocked by pre-existing issues on day one. The only things that will fail CI are genuine bugs, hooks called conditionally, hooks called outside of components, and similarreact-hooks/rules-of-hooksviolations.The React Compiler rules (shipped as part of
eslint-plugin-react-hooksv7) are also set towarn. We are not currently using the React Compiler, and fixing all 49 violations isn't worth doing as part of a lint setup ticket. The decision is documented in the-brain atdocs/product/decisions/react-compiler.md.What was fixed to get to zero errors
Running the linter on the existing codebase produced 97 errors. All of them are resolved in this PR:
npm run lint:fix): 29prefer-constand irregular whitespace violations across providers, resources, and pageserrortowarn(49 violations — pre-existing patterns, not new problems)// commentlines inside JSX children inroutes/ocotillo.tsx, wrapped in{/* */}"and'characters in JSX text inGameResults.tsxandTypographyPage.tsx, replaced with"and'Functiontype: replaced bareFunctiontypes inutils/Link.tsxwith explicit signatureslexicon/list.tsx—useExportwas called inside aheaderButtonsrender function; extracted as a properLexiconHeaderButtonscomponentutils/Link.tsx—useLinkwas called insidelinkColumn; moved out and passed as a parameter, callers updatedcomponents/card/RecentWaterLevelObservations.tsx—useMemowas called after an early return; moved above itcomponents/MapComponent.tsx—useRefwas called inside a??expression (conditional); split into an unconditionaluseRefcall followed by the conditional assignmentWarnings remaining
725 warnings remain. They are not blocking anything and will be addressed incrementally:
@typescript-eslint/no-explicit-any@typescript-eslint/no-unused-varsreact-refresh/only-export-componentsreact-hooks/exhaustive-deps@typescript-eslint/no-empty-object-type