185 lines
5.7 KiB
JavaScript
185 lines
5.7 KiB
JavaScript
// ESLint flat config
|
||
// 两个 block:
|
||
// 1. main / preload / scripts/ —— Node CJS 环境(require / module / process / __dirname)
|
||
// 2. src/ —— 浏览器 ESM 环境(无 Node globals;importmap 暴露的 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 globals(describe/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',
|
||
// Electron(main/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 API(main/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(...) 调用
|
||
},
|
||
},
|
||
];
|