- devDependencies: eslint 10 / typescript-eslint 8 / eslint-plugin-react-hooks 7 / globals / @eslint/js(ESLint 10 起 @eslint/js 不再随 eslint 自带,需显式安装) - eslint.config.js:@eslint/js recommended + typescript-eslint recommended(非 type-checked)+ react-hooks recommended(v7 的 React Compiler 语义规则档整体关闭——57 处存量误报,保留经典 rules-of-hooks / exhaustive-deps 双规则) - globals 分域:src/client → browser;src 根 / scripts / 根级 config → node;tests → node+browser - reportUnusedDisableDirectives: error 揪孤儿豁免;no-unused-vars 对齐仓库既有 _ 前缀占位约定 - package.json 增加 lint script(eslint .)
89 lines
3.1 KiB
JavaScript
89 lines
3.1 KiB
JavaScript
// ESLint flat config(最小规则集):
|
||
// - 基础:@eslint/js recommended + typescript-eslint recommended(非 type-checked 档,
|
||
// 全量 type-checked 需要项目服务且更慢,当前收益不足以引入);
|
||
// - react-hooks recommended:client 侧是 React 重镇,依赖数组豁免注释
|
||
// (react-hooks/exhaustive-deps)由此规则消费;
|
||
// - globals 按运行域分治:client bundle → browser,host/脚本 → node,tests → 混合。
|
||
import js from '@eslint/js'
|
||
import globals from 'globals'
|
||
import reactHooks from 'eslint-plugin-react-hooks'
|
||
import tseslint from 'typescript-eslint'
|
||
|
||
export default tseslint.config(
|
||
// 构建产物 / 工具目录不参与 lint(node_modules 与点开头目录默认也不进)。
|
||
{
|
||
ignores: [
|
||
'lib/',
|
||
'dist/',
|
||
'coverage/',
|
||
'registry/',
|
||
'playwright-report/',
|
||
'test-results/',
|
||
'node_modules/',
|
||
'.worktrees/',
|
||
],
|
||
},
|
||
|
||
js.configs.recommended,
|
||
tseslint.configs.recommended,
|
||
reactHooks.configs.flat.recommended,
|
||
|
||
// react-hooks v7 的 recommended 捆绑了 React Compiler 语义规则(purity /
|
||
// immutability / refs / set-state-in-effect 等):本仓库对 CodeMirror / xterm
|
||
// 等命令式集成大量依赖 render 期读 ref、effect 内同步 setState 的既有模式,
|
||
// 57 处存量报错均为噪音级误报,先整体关闭该档,只保留经典双规则
|
||
// (rules-of-hooks / exhaustive-deps——后者消费代码里带理由的豁免注释)。
|
||
{
|
||
rules: Object.fromEntries(
|
||
[
|
||
'config',
|
||
'error-boundaries',
|
||
'gating',
|
||
'globals',
|
||
'immutability',
|
||
'incompatible-library',
|
||
'preserve-manual-memoization',
|
||
'purity',
|
||
'refs',
|
||
'set-state-in-effect',
|
||
'static-components',
|
||
'unsupported-syntax',
|
||
'use-memo',
|
||
].map(rule => [`react-hooks/${rule}`, 'off']),
|
||
),
|
||
},
|
||
|
||
// 孤儿 eslint-disable 注释(规则未实际触发)直接报错,防止豁免残留。
|
||
{ linterOptions: { reportUnusedDisableDirectives: 'error' } },
|
||
|
||
// no-unused-vars 对齐仓库既有约定:下划线前缀 = 刻意不用的占位(mock 桩等)。
|
||
{
|
||
rules: {
|
||
'@typescript-eslint/no-unused-vars': ['error', {
|
||
argsIgnorePattern: '^_',
|
||
varsIgnorePattern: '^_',
|
||
caughtErrorsIgnorePattern: '^_',
|
||
}],
|
||
},
|
||
},
|
||
|
||
// client bundle 运行在浏览器(portal 侧边栏 / 各视图 / 拦截层)。
|
||
{
|
||
files: ['src/client/**/*.{js,mjs,cjs,ts,tsx,jsx}'],
|
||
languageOptions: { globals: globals.browser },
|
||
},
|
||
|
||
// host 侧插件入口与构建/运维脚本跑在 Node。eslint.config.js 自身不 ignore:
|
||
// 它就是一个普通 ESM 脚本,走 js recommended + node globals 正常通过。
|
||
{
|
||
files: ['src/*.{js,mjs,cjs,ts}', 'scripts/**/*.{js,mjs,cjs,ts}', '*.config.ts', 'eslint.config.js'],
|
||
languageOptions: { globals: globals.node },
|
||
},
|
||
|
||
// tests:Node 里跑(vitest / fs fixtures),jsdom 组件测试又摸浏览器全局。
|
||
{
|
||
files: ['tests/**/*.{js,mjs,cjs,ts,tsx,jsx}'],
|
||
languageOptions: { globals: { ...globals.node, ...globals.browser } },
|
||
},
|
||
)
|