This commit is contained in:
2026-09-12 14:15:26 +08:00
commit 9c06d3f4be
99 changed files with 41853 additions and 0 deletions

184
eslint.config.js Normal file
View File

@@ -0,0 +1,184 @@
// ESLint flat config
// 两个 block
// 1. main / preload / scripts/ —— Node CJS 环境require / module / process / __dirname
// 2. src/ —— 浏览器 ESM 环境(无 Node globalsimportmap 暴露的 codemirror / @codemirror/* 是 ESM 模块,
// 不是 globals不写进 globals 表)
//
// 规则严格度按"项目当前状态可一键通过"为基线recommended + 关键 hygiene不强制风格化prettier 不上)。
const js = require('@eslint/js');
module.exports = [
// eslint.config.js 自身Node CJS
{
files: ['eslint.config.js'],
languageOptions: {
ecmaVersion: 2022,
sourceType: 'commonjs',
globals: {
require: 'readonly',
module: 'writable',
exports: 'writable',
},
},
},
// 全局忽略
{
ignores: [
'node_modules/**',
'dist/**',
'.playwright-mcp/**',
'scripts/_dbg-*.png',
'tmp-*.mjs', // 临时验证脚本
'scripts/**/*.mjs', // 一次性 ad-hoc debug 脚本playwright / repro 等),不是生产代码
'src/styles/**', // Stage 4 之后才有
'tests/**', // 测试文件用 vitest globalsdescribe/it/expect/vi
// 由 vitest.config.js 负责;不需要 ESLint 强校验。
],
},
// Block 1: Node CJS —— main / preload / scripts / shared
{
files: [
'main.js',
'main/**/*.js',
'preload.js',
'scripts/**/*.js',
'shared/**/*.js',
],
languageOptions: {
ecmaVersion: 2022,
sourceType: 'commonjs',
globals: {
// Node
process: 'readonly',
Buffer: 'readonly',
__dirname: 'readonly',
__filename: 'readonly',
module: 'readonly',
require: 'readonly',
exports: 'writable',
console: 'readonly',
setTimeout: 'readonly',
clearTimeout: 'readonly',
setInterval: 'readonly',
clearInterval: 'readonly',
setImmediate: 'readonly',
URL: 'readonly',
URLSearchParams: 'readonly',
// Electronmain/preload 直接 require 进来的)
app: 'readonly',
BrowserWindow: 'readonly',
ipcMain: 'readonly',
ipcRenderer: 'readonly',
contextBridge: 'readonly',
Menu: 'readonly',
Tray: 'readonly',
dialog: 'readonly',
shell: 'readonly',
screen: 'readonly',
nativeImage: 'readonly',
globalShortcut: 'readonly',
// preload 在 Electron sandbox 下能引用 window与 renderer 的隔离 window 不同)
window: 'readonly',
document: 'readonly',
// Node 18+ 内置 Web APImain/ai.js 用 fetch + AbortController
fetch: 'readonly',
AbortController: 'readonly',
AbortSignal: 'readonly',
},
},
rules: {
...js.configs.recommended.rules,
'no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
'no-empty': ['error', { allowEmptyCatch: true }],
'no-async-promise-executor': 'off', // preload 有 await in new Promise 的合法用法
},
},
// Block 2: renderer ESM —— src/**
{
files: ['src/**/*.js'],
languageOptions: {
ecmaVersion: 2022,
sourceType: 'module',
globals: {
// Browser
window: 'readonly',
document: 'readonly',
navigator: 'readonly',
location: 'readonly',
history: 'readonly',
localStorage: 'readonly',
sessionStorage: 'readonly',
console: 'readonly',
setTimeout: 'readonly',
clearTimeout: 'readonly',
setInterval: 'readonly',
clearInterval: 'readonly',
requestAnimationFrame: 'readonly',
cancelAnimationFrame: 'readonly',
IntersectionObserver: 'readonly',
fetch: 'readonly',
AbortController: 'readonly',
AbortSignal: 'readonly',
getComputedStyle: 'readonly',
queueMicrotask: 'readonly',
MutationObserver: 'readonly',
crypto: 'readonly',
Element: 'readonly',
HTMLElement: 'readonly',
HTMLInputElement: 'readonly',
HTMLTextAreaElement: 'readonly',
Event: 'readonly',
CustomEvent: 'readonly',
KeyboardEvent: 'readonly',
MouseEvent: 'readonly',
DOMParser: 'readonly',
URL: 'readonly',
URLSearchParams: 'readonly',
Blob: 'readonly',
File: 'readonly',
FileReader: 'readonly',
Promise: 'readonly',
Map: 'readonly',
Set: 'readonly',
WeakMap: 'readonly',
WeakSet: 'readonly',
Date: 'readonly',
Math: 'readonly',
JSON: 'readonly',
Number: 'readonly',
String: 'readonly',
Array: 'readonly',
Object: 'readonly',
Error: 'readonly',
TypeError: 'readonly',
RangeError: 'readonly',
Symbol: 'readonly',
Proxy: 'readonly',
Reflect: 'readonly',
parseInt: 'readonly',
parseFloat: 'readonly',
isNaN: 'readonly',
isFinite: 'readonly',
encodeURIComponent: 'readonly',
decodeURIComponent: 'readonly',
// CodeMirror 是 ESM 模块,通过 importmap 解析 —— 不属于 globals
},
},
rules: {
...js.configs.recommended.rules,
'no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
'no-empty': ['error', { allowEmptyCatch: true }],
},
},
// 全局规则调整(适用于两个 block
{
rules: {
'no-undef': 'error', // 强制renderer 不能用 process.*
'no-prototype-builtins': 'off', // 旧代码里有 obj.hasOwnProperty(...) 调用
},
},
];