Files
Python-Profiler-Visualizer/.eslintrc.cjs
2026-09-12 14:19:56 +08:00

141 lines
6.3 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* ESLint 配置 —— 只 lint renderer 业务代码src/renderer, src/shared, src/preload
*
* 不 lint src/main那里是 Electron 主进程,跑的是 Node 18 的能力,规则集合不一样,
* 引入会让 CI 噪声很大、价值很低。先把 renderer 这一层质量守住。
*
* 主要规则选型:
* - "@typescript-eslint/recommended-type-checked" 启用类型感知规则,副作用比 no-type-checked 系列少。
* - react/jsx-runtime自动从 react/jsx-runtime 引入),不用 import React。
* - jsx-a11y 全套,覆盖 ARIA、键盘、对比度前的标签语义颜色用 tailwind不在 a11y 范围里)。
* - 自定义规则:
* * no-restricted-syntax 禁止 console.* 在 src 代码里残留(要日志走 electron log
* * no-restricted-imports 禁掉 cross-process importrenderer 永远不该 import src/main
*
* 故意没开prettier用 prettier --check、import/order争论太多收益太小
*/
module.exports = {
root: true,
env: { browser: true, es2022: true, node: true },
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
ecmaFeatures: { jsx: true },
project: ['./tsconfig.json'],
tsconfigRootDir: __dirname
},
settings: { react: { version: 'detect' } },
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended-type-checked',
'plugin:react/recommended',
'plugin:react/jsx-runtime',
'plugin:react-hooks/recommended',
'plugin:jsx-a11y/recommended'
],
plugins: ['@typescript-eslint', 'react', 'react-hooks', 'jsx-a11y'],
ignorePatterns: [
'out/**',
'node_modules/**',
'dist/**',
'release/**',
'coverage/**',
'test-results/**',
'playwright-report/**',
'*.config.cjs',
'*.config.js',
'*.config.ts',
'.eslintrc.cjs',
'tailwind.config.cjs',
'postcss.config.cjs'
],
rules: {
// 显式 any 在这种规模的代码里其实有必要 —— @typescript-eslint/no-explicit-any 在 type-checked
// 模式下噪声太大(每个 IpcError catch 都会撞)。先关掉,等真有滥用时再开。
'@typescript-eslint/no-explicit-any': 'off',
// ts-ignore 用一行注释比挨个枚举类型便宜;只在违规真的不可避免时才允许
'@typescript-eslint/ban-ts-comment': ['warn', { 'ts-ignore': 'allow-with-description' }],
// React 17+ 没用 React.* API没必要强制默认写 React import
'react/react-in-jsx-scope': 'off',
'react/prop-types': 'off',
// 性能优化 / a11y 都需要 conditional roles比如 isSelected ? 'true' : undefined
'react/jsx-boolean-value': ['warn', 'never'],
// hooks 依赖数组:我们有 useEffect 用 useRef 当 token 守门react-hooks 会误报
'react-hooks/exhaustive-deps': 'warn',
// a11y 误报role="button" 在 <tr>/<g> 上是正确做法jsx-a11y v6 仍把它当 interactive
// 控件要求 tabIndex规则偶尔会和组件本身定的 roving tabindex 打架 → warn 不 block
'jsx-a11y/no-noninteractive-element-interactions': 'warn',
'jsx-a11y/click-events-have-key-events': 'warn',
// src/shared 是纯类型和常量,应该优先用 type 而不是 interface —— 同名 interface 合并
// 在 React 项目里几乎总是误用
'@typescript-eslint/consistent-type-imports': ['warn', { prefer: 'type-imports' }],
// onClick={async () => await foo()} 在 React 里是常见且正确的写法 —— React 会忽略返回
// 的 Promise这是 React 的设计缺陷,但用 ESLint 卡它没有收益,只会让所有按钮代码都
// 包一层 void 包装)。同理表单 onSubmit。
'@typescript-eslint/no-misused-promises': [
'error',
{ checksVoidReturn: { arguments: false, attributes: false } }
],
'no-restricted-syntax': [
'warn',
{
// renderer 里允许 console.error 用于诊断,但不允许 console.log —— 那是 debug 残留
selector: "CallExpression[callee.object.name='console'][callee.property.name!=/^(error|warn)$/]",
message: 'renderer 进程不要留 console.log/warn日志走 main 进程的 electron-log。'
}
],
'no-restricted-imports': [
'error',
{
// 阻止 renderer 跨进程边界拉主进程代码 —— 一旦发生contextBridge 的隔离就破了
patterns: [
{
group: ['**/src/main/**', '**/main/**'],
message: 'renderer 不允许 import src/main/;走 preload 暴露的 IPC 接口。'
}
]
}
]
},
overrides: [
{
// 测试文件允许 any 和未使用变量fixture/dummy 经常违反。console.log 也允许——
// 测试期间的诊断输出没法走 electron-log。require-await 在 mock fn 里大量误报
// vi.fn().mockResolvedValue 总是返回 Promise写成 async 是统一形式):
files: ['**/*.test.{ts,tsx}', '**/__tests__/**', 'e2e/**'],
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
'no-restricted-syntax': 'off',
'@typescript-eslint/require-await': 'off'
}
},
{
// e2e 测试禁止固定 sleepwaitForTimeout(>=1000) 几乎一定意味着「等某件事完成」,
// 而这件事可以用 web-first 断言expect().toBeVisible/toHaveText/toPass
// 表达成「等某件事真的发生」。固定 sleep 在 CI 慢的时候假阴、快的机器上又假阳。
// 例外≤50ms 紧跟在 keyboard.press / type 后面,给 DOM 派发的事件循环时间,
// 这种替代方案不如直接 sleep 直观。
files: ['e2e/**'],
rules: {
'no-restricted-syntax': [
'error',
{
selector:
"CallExpression[callee.object.name='page'][callee.property.name='waitForTimeout'][arguments.0.value>=1000]",
message:
'禁止固定 sleep >=1s。用 web-first 断言代替expect.toBeVisible/toPass 等CI 慢机器才不会假阴、快的机器才不会假阳。'
}
]
}
},
{
files: ['src/preload/**'],
// preload 在沙箱里跑,没有 Node DOM但有 Node 全局
env: { browser: false, node: true }
}
]
}