Skip to content

Commit 7b5c7dd

Browse files
authored
Merge pull request omdsh-dev#536 from omdsh-dev/feat/eslint
feat(lint): 引入 ESLint flat config 并接入 CI 与 Makefile
2 parents f8bb301 + 98e9a4f commit 7b5c7dd

45 files changed

Lines changed: 1529 additions & 94 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ jobs:
4141
run: pnpm install --frozen-lockfile
4242
- name: Typecheck
4343
run: pnpm typecheck
44+
- name: Lint
45+
run: pnpm lint
4446
- name: Test
4547
run: pnpm test
4648
- name: Build
@@ -88,6 +90,8 @@ jobs:
8890
run: pnpm install --frozen-lockfile
8991
- name: Typecheck
9092
run: pnpm typecheck
93+
- name: Lint
94+
run: pnpm lint
9195
- name: Test
9296
run: pnpm test
9397
- name: Build

.github/workflows/release.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,15 +88,19 @@ jobs:
8888
- name: Typecheck
8989
run: pnpm typecheck
9090

91+
- name: Lint
92+
run: pnpm lint
93+
9194
- name: Test
9295
run: pnpm test
9396

9497
- name: Build
9598
run: pnpm build
9699

97100
# The consumer-facing declaration surface guard — mirrors the ci.yml
98-
# verification order (typecheck → test → build → check:consumer-types)
99-
# so a release is gated on the same checks a PR runs.
101+
# verification order (typecheck → lint → test → build →
102+
# check:consumer-types) so a release is gated on the same checks a PR
103+
# runs.
100104
- name: Check consumer type surface
101105
run: pnpm check:consumer-types
102106

Makefile

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# dsh-better-sidebar 命令面薄封装:目标仅转发 package.json scripts(唯一事实源),
22
# 新增/改名 script 不需要动这里;本文件只补目标发现(help)与 CI 门禁聚合
33
# (check / mount / mount-aggregate / registry)。
4-
# 注:lint 目标留给引入 ESLint 的后续 PR。
54

65
.DEFAULT_GOAL := help
76

@@ -17,11 +16,14 @@ build: ## 构建(清 lib/ → tsc → tsdown)
1716
typecheck: ## 类型检查(tsc --noEmit)
1817
pnpm typecheck
1918

19+
lint: ## 代码检查(eslint .,flat config 最小规则集)
20+
pnpm lint
21+
2022
test: ## 单元测试(vitest run)
2123
pnpm test
2224

23-
check: ## 聚合校验门禁:typecheck → build → test → check:consumer-types(对齐 CI)
24-
pnpm typecheck && pnpm build && pnpm test && pnpm check:consumer-types
25+
check: ## 聚合校验门禁:typecheck → lint → build → test → check:consumer-types(对齐 CI)
26+
pnpm typecheck && pnpm lint && pnpm build && pnpm test && pnpm check:consumer-types
2527

2628
clean: ## 清理构建产物与测试报告(lib/、*.tgz、playwright-report/、test-results/)
2729
rm -rf lib playwright-report test-results
@@ -39,4 +41,4 @@ mount-aggregate: ## 聚合双挂载回归:build + pack → pnpm test:mount:agg
3941
registry: ## 组装 plugin-registry 暂存(registry/,不入库):build → node scripts/package-registry.mjs
4042
pnpm build && node scripts/package-registry.mjs
4143

42-
.PHONY: help install build typecheck test check clean pack mount mount-aggregate registry
44+
.PHONY: help install build typecheck lint test check clean pack mount mount-aggregate registry

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,7 @@ GitHub topic [`dsh-better-sidebar`](https://github.com/topics/dsh-better-sidebar
524524
```sh
525525
pnpm install # @deepseek-ai/* devDependencies 已发布(基线 0.1.2-rc.1,next dist-tag),直接解析、无需令牌
526526
pnpm typecheck # tsc --noEmit
527+
pnpm lint # eslint .(flat config:js + typescript-eslint + react-hooks recommended)
527528
pnpm build # → lib/index.js + lib/invariant.js + lib/client.js + lib/client-registry.js + lib/types
528529
pnpm test # vitest(含 manifest 一致性守卫,需先 build)
529530
pnpm watch # tsdown --watch

README_EN.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,7 @@ The dashed cards at the end of the "Sidebar content" / "File viewers" grids in t
519519
```sh
520520
pnpm install # @deepseek-ai/* devDependencies resolve (baseline 0.1.2-rc.1, next dist-tag) — no token needed
521521
pnpm typecheck # tsc --noEmit
522+
pnpm lint # eslint . (flat config: js + typescript-eslint + react-hooks recommended)
522523
pnpm build # → lib/index.js + lib/invariant.js + lib/client.js + lib/client-registry.js + lib/types
523524
pnpm test # vitest (includes manifest consistency guard; build first)
524525
pnpm watch # tsdown --watch

eslint.config.js

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// ESLint flat config(最小规则集):
2+
// - 基础:@eslint/js recommended + typescript-eslint recommended(非 type-checked 档,
3+
// 全量 type-checked 需要项目服务且更慢,当前收益不足以引入);
4+
// - react-hooks recommended:client 侧是 React 重镇,依赖数组豁免注释
5+
// (react-hooks/exhaustive-deps)由此规则消费;
6+
// - globals 按运行域分治:client bundle → browser,host/脚本 → node,tests → 混合。
7+
import js from '@eslint/js'
8+
import globals from 'globals'
9+
import reactHooks from 'eslint-plugin-react-hooks'
10+
import tseslint from 'typescript-eslint'
11+
12+
export default tseslint.config(
13+
// 构建产物 / 工具目录不参与 lint(node_modules 与点开头目录默认也不进)。
14+
{
15+
ignores: [
16+
'lib/',
17+
'dist/',
18+
'coverage/',
19+
'registry/',
20+
'playwright-report/',
21+
'test-results/',
22+
'node_modules/',
23+
'.worktrees/',
24+
],
25+
},
26+
27+
js.configs.recommended,
28+
tseslint.configs.recommended,
29+
reactHooks.configs.flat.recommended,
30+
31+
// react-hooks v7 的 recommended 捆绑了 React Compiler 语义规则(purity /
32+
// immutability / refs / set-state-in-effect 等):本仓库对 CodeMirror / xterm
33+
// 等命令式集成大量依赖 render 期读 ref、effect 内同步 setState 的既有模式,
34+
// 57 处存量报错均为噪音级误报,先整体关闭该档,只保留经典双规则
35+
// (rules-of-hooks / exhaustive-deps——后者消费代码里带理由的豁免注释)。
36+
{
37+
rules: Object.fromEntries(
38+
[
39+
'config',
40+
'error-boundaries',
41+
'gating',
42+
'globals',
43+
'immutability',
44+
'incompatible-library',
45+
'preserve-manual-memoization',
46+
'purity',
47+
'refs',
48+
'set-state-in-effect',
49+
'static-components',
50+
'unsupported-syntax',
51+
'use-memo',
52+
].map(rule => [`react-hooks/${rule}`, 'off']),
53+
),
54+
},
55+
56+
// 孤儿 eslint-disable 注释(规则未实际触发)直接报错,防止豁免残留。
57+
{ linterOptions: { reportUnusedDisableDirectives: 'error' } },
58+
59+
// no-unused-vars 对齐仓库既有约定:下划线前缀 = 刻意不用的占位(mock 桩等)。
60+
{
61+
rules: {
62+
'@typescript-eslint/no-unused-vars': ['error', {
63+
argsIgnorePattern: '^_',
64+
varsIgnorePattern: '^_',
65+
caughtErrorsIgnorePattern: '^_',
66+
}],
67+
},
68+
},
69+
70+
// client bundle 运行在浏览器(portal 侧边栏 / 各视图 / 拦截层)。
71+
{
72+
files: ['src/client/**/*.{js,mjs,cjs,ts,tsx,jsx}'],
73+
languageOptions: { globals: globals.browser },
74+
},
75+
76+
// host 侧插件入口与构建/运维脚本跑在 Node。eslint.config.js 自身不 ignore:
77+
// 它就是一个普通 ESM 脚本,走 js recommended + node globals 正常通过。
78+
{
79+
files: ['src/*.{js,mjs,cjs,ts}', 'scripts/**/*.{js,mjs,cjs,ts}', '*.config.ts', 'eslint.config.js'],
80+
languageOptions: { globals: globals.node },
81+
},
82+
83+
// tests:Node 里跑(vitest / fs fixtures),jsdom 组件测试又摸浏览器全局。
84+
{
85+
files: ['tests/**/*.{js,mjs,cjs,ts,tsx,jsx}'],
86+
languageOptions: { globals: { ...globals.node, ...globals.browser } },
87+
},
88+
)

package.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@
8282
"test:mount": "bash scripts/e2e-mount.sh",
8383
"test:mount:aggregate": "bash scripts/e2e-aggregate-mount.sh",
8484
"clean": "node -e \"require('node:fs').rmSync('lib',{recursive:true,force:true})\"",
85-
"check:consumer-types": "bash scripts/check-consumer-types.sh"
85+
"check:consumer-types": "bash scripts/check-consumer-types.sh",
86+
"lint": "eslint ."
8687
},
8788
"license": "MIT",
8889
"peerDependencies": {
@@ -179,6 +180,11 @@
179180
"tsdown": "^0.22.2",
180181
"typescript": "^5.6.0",
181182
"unrun": "^0.2.39",
182-
"vitest": "^4.1.8"
183+
"vitest": "^4.1.8",
184+
"@eslint/js": "^10.0.1",
185+
"eslint": "^10.9.1",
186+
"eslint-plugin-react-hooks": "^7.1.1",
187+
"globals": "^17.12.0",
188+
"typescript-eslint": "^8.69.0"
183189
}
184190
}

0 commit comments

Comments
 (0)