build(lint): add ESLint 9 + eslint-plugin-react-hooks/react-refresh (R1)
There was no linting at all — nothing enforced rules-of-hooks (conditional-hook crashes) or exhaustive-deps (stale closures) across 125 client components/pages. Added an ESLint flat config (eslint.config.mjs) scoped to client/, an 'npm run lint' script, and the devDeps. First run: 0 rules-of-hooks violations (good), 6 errors + 13 exhaustive-deps warnings to work through next. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
38417ad8da
commit
c679022592
|
|
@ -0,0 +1,36 @@
|
|||
import js from '@eslint/js';
|
||||
import globals from 'globals';
|
||||
import reactHooks from 'eslint-plugin-react-hooks';
|
||||
import reactRefresh from 'eslint-plugin-react-refresh';
|
||||
|
||||
// Flat config scoped to the React client. The point is enforcement of the two
|
||||
// rules that catch real React bugs — rules-of-hooks (conditional hooks) and
|
||||
// exhaustive-deps (stale closures) — which nothing previously checked. Server
|
||||
// code (CommonJS Node) is out of scope here; `npm run check:server` covers it.
|
||||
export default [
|
||||
{ ignores: ['dist/**', 'node_modules/**', 'coverage/**', 'client/**/*.test.*'] },
|
||||
{
|
||||
files: ['client/**/*.{js,jsx}'],
|
||||
languageOptions: {
|
||||
ecmaVersion: 2023,
|
||||
sourceType: 'module',
|
||||
globals: { ...globals.browser },
|
||||
parserOptions: { ecmaFeatures: { jsx: true } },
|
||||
},
|
||||
plugins: {
|
||||
'react-hooks': reactHooks,
|
||||
'react-refresh': reactRefresh,
|
||||
},
|
||||
rules: {
|
||||
...js.configs.recommended.rules,
|
||||
// The two that matter most for correctness:
|
||||
'react-hooks/rules-of-hooks': 'error',
|
||||
'react-hooks/exhaustive-deps': 'warn',
|
||||
// HMR safety (Vite fast-refresh); allow non-component constant exports.
|
||||
'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
|
||||
// Keep the js-recommended noise as warnings so hook signal isn't drowned out.
|
||||
'no-unused-vars': ['warn', { varsIgnorePattern: '^[A-Z_]', argsIgnorePattern: '^_' }],
|
||||
'no-empty': ['warn', { allowEmptyCatch: true }],
|
||||
},
|
||||
},
|
||||
];
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -9,6 +9,7 @@
|
|||
"dev": "concurrently \"npm run dev:api\" \"npm run dev:ui\"",
|
||||
"build": "vite build",
|
||||
"check:server": "find server.js db middleware routes services utils -name '*.js' -print0 | xargs -0 -n1 node --check",
|
||||
"lint": "eslint client",
|
||||
"check": "npm run check:server && npm run build",
|
||||
"test": "node --test tests/*.test.js",
|
||||
"test:client": "vitest run",
|
||||
|
|
@ -64,11 +65,16 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@axe-core/playwright": "^4.10.1",
|
||||
"@eslint/js": "^9.39.4",
|
||||
"@playwright/test": "^1.50.1",
|
||||
"@testing-library/react": "^16.3.2",
|
||||
"@vitejs/plugin-react": "^4.3.3",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"concurrently": "^9.1.0",
|
||||
"eslint": "^9.39.4",
|
||||
"eslint-plugin-react-hooks": "^5.2.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.26",
|
||||
"globals": "^17.7.0",
|
||||
"jsdom": "^29.1.1",
|
||||
"postcss": "^8.4.47",
|
||||
"tailwindcss": "^3.4.14",
|
||||
|
|
|
|||
Loading…
Reference in New Issue