my-code-style 1.4.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,131 @@
1
+ ## 变更日志
2
+
3
+ ## [1.6.0](https://github.com/myvn/codeStyle/compare/v1.4.0...v1.6.0) (2026-09-18)
4
+
5
+ ### 🐛 Bug Fixes | Bug 修复
6
+
7
+ - 修复 ESLint 版本/样式检测误判、规则冲突与 scope 生成缺陷 ([033967b](https://github.com/myvn/codeStyle/commit/033967b0efadbb705bdafe5d4dfc34dbc90578c2))
8
+ - 修复 Flat Config 缺 eslint:recommended、Prettier 选项漂移等 7 类问题 ([e4533bb](https://github.com/myvn/codeStyle/commit/e4533bbdaf5752146289a2b4e044ce59658c9453))
9
+
10
+ ### ✨ Features | 新功能
11
+
12
+ - **diagnose:** ⑤ 拆分排队来源:纯 git 链膨胀 vs 完整链膨胀 vs 错峰启动 ([5caa437](https://github.com/myvn/codeStyle/commit/5caa4372d6ebbc52e19ec771b65d9a0edf041d63))
13
+ - **diagnose:** 增加 ⑤ 并发压力段,量"单个耗时被并发放大多少倍" ([df060d5](https://github.com/myvn/codeStyle/commit/df060d56cecfa7f3b830864cc01082ee14583662))
14
+ - **diagnose:** 对照 fixture 落在仓库内 vs 系统临时目录 ([7ea7fdc](https://github.com/myvn/codeStyle/commit/7ea7fdc6f913dcad1e76fb110241f875a204c341))
15
+ - **diagnose:** 新增 npm run diagnose,定位"一次提交到底花在哪" ([61dbfdb](https://github.com/myvn/codeStyle/commit/61dbfdb99813384097cf2f243b31d20c84695cbd))
16
+ - **init:** 补全 peer 体检并按包管理器输出命令,新增初始化链路文档 ([0396198](https://github.com/myvn/codeStyle/commit/03961983be3a6f8cda96d4047450e7595ffefb97))
17
+ - **sweep:** 新增 --suite 过滤与 npm run sweep,给本机找最佳并发 ([d65254d](https://github.com/myvn/codeStyle/commit/d65254d1c9ef3277fbc23dc87bb6285d5ef3829c))
18
+
19
+ ## [1.5.0](https://github.com/myvn/codeStyle/compare/v1.4.0...v1.5.0) (2026-09-18)
20
+
21
+ ### 🐛 Bug Fixes | Bug 修复
22
+
23
+ - 修复 ESLint 版本/样式检测误判、规则冲突与 scope 生成缺陷 ([033967b](https://github.com/myvn/codeStyle/commit/033967b0efadbb705bdafe5d4dfc34dbc90578c2))
24
+ - 修复 Flat Config 缺 eslint:recommended、Prettier 选项漂移等 7 类问题 ([e4533bb](https://github.com/myvn/codeStyle/commit/e4533bbdaf5752146289a2b4e044ce59658c9453))
25
+
26
+ ### ✨ Features | 新功能
27
+
28
+ - **diagnose:** ⑤ 拆分排队来源:纯 git 链膨胀 vs 完整链膨胀 vs 错峰启动 ([5caa437](https://github.com/myvn/codeStyle/commit/5caa4372d6ebbc52e19ec771b65d9a0edf041d63))
29
+ - **diagnose:** 增加 ⑤ 并发压力段,量"单个耗时被并发放大多少倍" ([df060d5](https://github.com/myvn/codeStyle/commit/df060d56cecfa7f3b830864cc01082ee14583662))
30
+ - **diagnose:** 对照 fixture 落在仓库内 vs 系统临时目录 ([7ea7fdc](https://github.com/myvn/codeStyle/commit/7ea7fdc6f913dcad1e76fb110241f875a204c341))
31
+ - **diagnose:** 新增 npm run diagnose,定位"一次提交到底花在哪" ([61dbfdb](https://github.com/myvn/codeStyle/commit/61dbfdb99813384097cf2f243b31d20c84695cbd))
32
+ - **init:** 补全 peer 体检并按包管理器输出命令,新增初始化链路文档 ([0396198](https://github.com/myvn/codeStyle/commit/03961983be3a6f8cda96d4047450e7595ffefb97))
33
+ - **sweep:** 新增 --suite 过滤与 npm run sweep,给本机找最佳并发 ([d65254d](https://github.com/myvn/codeStyle/commit/d65254d1c9ef3277fbc23dc87bb6285d5ef3829c))
34
+
35
+ ## [1.4.0](https://github.com/myvn/codeStyle/compare/v1.2.0...v1.4.0) (2026-09-17)
36
+
37
+ ### 🐛 Bug Fixes | Bug 修复
38
+
39
+ - **commitlint:** guessCurrentScope 仅基于暂存区推断并补充频次投票与全场景回归 ([3f5f8ea](https://github.com/myvn/codeStyle/commit/3f5f8ea1a4526621006025ce2d86608dd53e9b2d))
40
+ - harden initialization and lint workflows with integration tests ([7079998](https://github.com/myvn/codeStyle/commit/707999895ac4d80d311537bd833584694c7a8510))
41
+ - **stylelint:** 支持混合 SCSS 与 Less 工程并在组件内嵌/独立样式中全量检查与修复 ([e5a1b7e](https://github.com/myvn/codeStyle/commit/e5a1b7e4992f40cf6b4f97fa75e3c755b57fb257))
42
+
43
+ ### ✨ Features | 新功能
44
+
45
+ - **core:** upgrade cli init, relax stylelint/eslint rules and bump v1.3.1 ([285c49b](https://github.com/myvn/codeStyle/commit/285c49b1f07707f7f998308d37f718e8d0af0d19))
46
+ - **init:** 支持 ESM versionrc、JSX/TSX 检查、版本识别强化与初始化事务回滚 ([89e8eb6](https://github.com/myvn/codeStyle/commit/89e8eb6677db00802636201148119d1fe208abe3))
47
+
48
+ ## 1.3.1 (2026-09-16)
49
+
50
+ ### Bug Fixes
51
+
52
+ - **stylelint:** 放行 SCSS `@extend` 类继承语法(`scss/at-extend-no-missing-placeholder: null`),放行空样式块(`block-no-empty: null`)
53
+ - **stylelint:** 内置 `ignoreFiles`,自动忽略 `**/assets/iconfont/**`、`**/public/**` 及压缩文件
54
+ - **eslint:** 允许 `// @ts-ignore` 注释(`@typescript-eslint/ban-ts-comment: off`)及 `{}` 类型(`@typescript-eslint/no-empty-object-type: off`)
55
+ - **eslint:** 放行无用表达式报错(`no-unused-expressions: off`),Flat Config 默认忽略 `**/assets/iconfont/**` 与 `**/public/**`,避免历史或第三方资源阻断提交
56
+
57
+ ## 1.3.0 (2026-09-16)
58
+
59
+ ### Features
60
+
61
+ - **init:** 智能识别工程类型(uni-app / Vue 3 / Node TS 基础库),按需分层生成配置
62
+ - **init:** ESLint 检测支持 peerDependencies,未配置项目默认优先采用现代 Flat Config (ESLint 9+)
63
+ - **init:** 无样式依赖的纯代码项目自动跳过 Stylelint 配置与任务挂载
64
+ - **init:** 内置 `.gitignore` 模板,项目缺失时自动生成,杜绝误暂存 `node_modules`
65
+ - **init:** 补齐 Stylelint 配套全量预设包及 `@commitlint/config-conventional` 到一键安装提示
66
+ - **init:** `lint-staged` 写入改为整块规范化覆盖,彻底消除规则重复执行
67
+ - **core:** 工具项目自身全面规范化,接入 ESLint 9 Flat Config 与 Husky 9 提交拦截
68
+
69
+ ### Bug Fixes
70
+
71
+ - **eslint:** 修复 `eslintConfigPrettier` 顺序问题,置于配置末尾消除引号冲突
72
+ - **eslint:** 放行 CommonJS 配置文件(`*.config.js`、`.*rc.js`、`*.cjs`)中的 `require()` 语法
73
+ - **eslint:** 关闭 `indent` 与 `vue/html-indent`,缩进格式全权交由 Prettier 处理
74
+ - **eslint:** 关闭 `import-x/extensions` 强制扩展名规则,补齐 `**/*.vue` 文件匹配
75
+ - **stylelint:** 补齐宽松规则,放行现代伪类语法、选择器嵌套及层叠特异性限制
76
+ - **husky:** 移除已废弃的 `husky.sh` 引用,升级全面兼容 Husky 9
77
+ - **commitlint:** 重构 `guessCurrentScope`,提升跨平台路径及多文件暂存匹配精准度
78
+ - **pkg:** 全部 31 项 `peerDependencies` 补充 `peerDependenciesMeta` 为 `optional`
79
+
80
+ ## 1.2.0 (2026-08-28)
81
+
82
+ ### Features
83
+
84
+ - 一键安装命令带上版本号 a58ddf7
85
+ - 一键安装提示,输出包含 my-code-style 的完整安装命令 3916ddd
86
+ - 安装命令分行展示,避免终端截断 3d4ab9c
87
+ - 添加 --version / -v 查看版本命令 14d6605
88
+ - 添加 Less 专用 stylelint 配置,init 脚本自动选择 be34547
89
+
90
+ ### Bug Fixes
91
+
92
+ - **eslint:** 修复 ESLint v8/v9 规则覆盖、解析器配置及脚手架生成逻辑 5b4e357
93
+ - peerDependencies 改用 ^ 范围,限制次版本号 b8deccd
94
+ - 修复 init 输出步骤号跳跃(1→3→4) 5248766
95
+ - 修复项目自身 ESLint 配置,添加 eslint.config.mjs 83f79a7
96
+ - 关闭 standard 带来的 style/quotes 冲突 0a21a6b
97
+ - 清理项目自身 init 脚本污染 c1b3b59
98
+
99
+ ## [1.1.0] - 2026-07-29
100
+
101
+ ### Breaking
102
+
103
+ - ESLint >= 9.0.0、@typescript-eslint >= 8.0.0
104
+ - eslint-config-prettier >= 10.1.8(修复 CVE-2025-54313)
105
+ - eslint-plugin-vue >= 10.0.0、husky >= 9.0.0、commitlint >= 19.0.0
106
+ - stylelint-config-recommended >= 16.0.0、lint-staged >= 16.0.0
107
+
108
+ ### Fixes
109
+
110
+ - `eslint-config-standard` 移入 peerDependenciesMeta optional(仅支持 ESLint 8)
111
+
112
+ ## [1.0.2] - 2026-07-29
113
+
114
+ ### Fixes
115
+
116
+ - bin 文件名去 `.cjs` 扩展名(修复 npm 警告)
117
+ - gitattributes 补充 `.ps1` 和 `.cmd/.bat` CRLF 支持
118
+ - `style/quotes` 和 `style/semi` 关闭(与 @stylistic 兼容)
119
+
120
+ ## [1.0.1] - 2026-07-28
121
+
122
+ ### Fixes
123
+
124
+ - 清理 init 脚本污染,.prettierrc.cjs 改为相对路径
125
+
126
+ ## [1.0.0] - 2026-07-28
127
+
128
+ ### Features
129
+
130
+ - Less 专用 stylelint 配置(`src/stylelint/less.cjs`)
131
+ - Flat Config 支持(ESLint 9+)
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 myvn
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -8,15 +8,43 @@ Lint/Format/Git 配置工程化 npm 包。适用于 Vue 3 + TypeScript + uni-app
8
8
 
9
9
  - [HTML 项目技术全景](docs/project-overview.html):下载或克隆仓库后,用浏览器直接打开,查看项目结构、配置架构、接入流程与维护注意事项;支持离线阅读和打印。
10
10
  - [Markdown 技术文档](TECHNICAL_DOC.md)
11
+ - [使用说明书](docs/manual.md):使用后的优点、带来的福利与解决的问题、完整使用步骤与常见问题 FAQ
12
+ - [初始化链路说明](docs/init-flow.md):`pnpm add -D my-code-style` + `npx my-code-style-init` 逐步做了什么、生成哪些文件、常见坑
11
13
 
12
- ## 快速开始
14
+ ## 怎么使用
15
+
16
+ 前置条件:Node ≥ 18、项目有合法 `package.json`、**已 `git init`**(husky 需要 git 仓库)。
13
17
 
14
18
  ```bash
15
- pnpm add -D my-code-style
16
- npx my-code-style-init
19
+ # 1. 安装配置包
20
+ pnpm add -D my-code-style # npm: npm i -D my-code-style
21
+
22
+ # 2. 先预览,再初始化(init 会覆盖已存在的 .prettierrc.cjs / hooks 等)
23
+ npx my-code-style-init --dry-run
24
+ npx my-code-style-init # 需保留旧文件时加 --backup
25
+
26
+ # 3. 按 CLI 输出的缺失依赖清单安装 peerDependencies(会按包管理器生成命令,别漏 typescript)
27
+ pnpm add -D my-code-style eslint@^9.0.0 typescript@^5.0.0 prettier@^3.0.0 ... # 以 CLI 实际输出为准
28
+
29
+ # 4. 初始化 hooks 并首次检查
30
+ pnpm prepare # npm: npm run prepare
31
+ pnpm lint
17
32
  ```
18
33
 
19
- init 脚本会自动检测项目技术栈类型(uni-app / Vue 3 / Node 基础库)、ESLint 版本和 CSS 预处理器,自动按需生成对应的配置文件。
34
+ init 脚本会自动检测技术栈类型(uni-app / Vue 3 / Node 基础库)、ESLint 版本、CSS 预处理器和包管理器,按需生成配置文件,并在结尾列出尚未安装的 peerDependencies 与对应安装命令。
35
+
36
+ 初始化后:`lint-staged` 会在 `git commit` 时自动修复暂存文件,`commitlint` 校验提交信息,`pnpm release` 生成版本与 CHANGELOG。全过程细节见 [docs/init-flow.md](docs/init-flow.md),收益与代价评估见 [docs/manual.md](docs/manual.md)。
37
+
38
+ ### 使用后的变化(速览)
39
+
40
+ | 维度 | 使用前 | 使用后 |
41
+ | ---------- | ---------------------------- | ------------------------------------------------- |
42
+ | 代码格式 | 各自编辑器配置 | 全仓库统一(4 空格 / 无分号 / 双引号 / 行宽 100) |
43
+ | 提交 | 靠自觉,问题留到评审 | pre-commit 自动修复,修不好的挡下提交 |
44
+ | 提交信息 | 自由文本 | conventional commits 强校验 + `pnpm cz` 引导 |
45
+ | 版本与日志 | 手工改版本、手工写 CHANGELOG | `pnpm release` 自动递增并生成 CHANGELOG |
46
+ | 样式代码 | 基本无人检查 | stylelint 覆盖 SCSS/Less/Vue 内嵌样式 |
47
+ | 规则同步 | 每个项目各抄一份 | 升级一个依赖版本,全项目生效 |
20
48
 
21
49
  ## 生成的文件
22
50
 
@@ -131,7 +159,7 @@ npx my-code-style-init [--dry-run] [--backup] [--version|-v] [--help|-h]
131
159
 
132
160
  ## 特性
133
161
 
134
- - **双引号**:`quotes: ["error", "double", { avoidEscape: false, allowTemplateLiterals: true }]`
162
+ - **双引号**:`quotes: ["error", "double", { avoidEscape: true, allowTemplateLiterals: true }]`(`avoidEscape` 必须为 `true`,否则与 Prettier 的转义策略冲突,`--fix` 无法消除报错)
135
163
  - **4 空格缩进**:`tabWidth: 4`(由 Prettier 全权统一格式化)
136
164
  - **无分号**:`semi: false`(`.nvue` 文件除外)
137
165
  - **行宽 100**:`printWidth: 100`
@@ -143,17 +171,165 @@ npx my-code-style-init [--dry-run] [--backup] [--version|-v] [--help|-h]
143
171
  - **严格暂存区 Scope 猜测**:`guessCurrentScope()` 严格只依据 Git 暂存区推断 scope,支持多目录频次投票、重命名、物理删除、中文路径与空格路径
144
172
  - **ESM 兼容的自动版本发布**:支持 CommonJS(`.versionrc.js`)与 ESM(`.versionrc.cjs`)工程无缝对接 standard-version,一键版本递增与 CHANGELOG 生成
145
173
 
174
+ ## 常见问题(使用中遇到的问题)
175
+
176
+ | 现象 | 原因 | 处理 |
177
+ | -------------------------------------------------------------------- | ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
178
+ | 只装了 `my-code-style`,`pnpm lint` 报找不到 eslint | peerDependencies 全部是 optional,不会自动安装 | 按 CLI 结尾输出的清单装全,**别漏 `typescript`**(`@typescript-eslint/parser` / `typescript-eslint` 的必需 peer) |
179
+ | `pnpm prepare` 输出 `.git can't be found`,hooks 不生效 | husky 必须在 git 仓库内执行 | 先 `git init`、再 `pnpm prepare`;验证 `git config core.hooksPath` 输出 `.husky/_` |
180
+ | 安装依赖报 `ERR_PNPM_IGNORED_BUILDS`(如 `unrs-resolver`) | pnpm 10+ 默认拦截依赖的构建脚本 | 执行 `pnpm approve-builds` 后重新安装,不是初始化失败 |
181
+ | `eslint` 声明 `>=8.0.0` 却生成了 Flat Config | 无上界范围 npm 实际会装 9,CLI 按 9 生成 | 确定留在 8 就把范围收紧到 `<9`(如 `~8.57.0`)后重跑 init |
182
+ | 重复 init 后,改过的 `.prettierrc.cjs` / hooks 被覆盖 | 除 ESLint 入口与已存在的 `.gitignore` 外,目标文件一律覆盖 | 先用 `--dry-run` 看清单、用 `--backup` 留档(备份含 `package.json`,目录会自动写入 `.gitignore`) |
183
+ | 自定义 `lint-staged` 分组消失 | `lint-staged` 为整体替换,避免残留失效分组 | 从 `.my-code-style-backup/package.json` 恢复后手动合并 |
184
+ | 提交时 lint 报错、提交失败 | 修不了的错误(语法错误、非法 CSS 属性)会阻止提交 | 按提示修复;紧急情况可用 `git commit --no-verify`,但请在 **CI 用 `pnpm lint` 兜底** |
185
+ | 提交信息被拒(`type may not be empty` / `subject may not be empty`) | 提交信息需符合 conventional commits | 用 `pnpm cz` 交互式生成;header 上限 108 字符 |
186
+ | 老项目已有 `.eslintrc.*`,init 只读退出 | ESLint 版本与配置格式冲突时 CLI 拒绝写入 | 先确认/迁移版本,再重跑 init |
187
+ | `pnpm release` 之后如何发布 | `release` 只生成版本、CHANGELOG、提交与 tag | 另行执行 `npm publish` |
188
+
189
+ 完整 FAQ(含更多场景与解释)见 [docs/manual.md](docs/manual.md#五使用中遇到的问题faq)。
190
+
146
191
  ## 测试套件
147
192
 
148
193
  ```bash
149
- npm test # 运行基础 CLI 与配置矩阵测试(52 项)
194
+ npm run test:all # 全量运行 152 项:用例明细 + 分类统计 + 最慢文件定位
195
+ npm run diagnose # 换机器后先跑它:进程 / git / 文件系统 / hooks 各占多少
196
+ npm run sweep # 给本机找最佳文件级并发(扫 integration 套件)
197
+ npm test # 只跑基础 CLI 与配置矩阵(70 项)
150
198
  npm run test:integration:setup # 安装现代化隔离依赖运行环境
151
- npm run test:integration # 运行 Flat Config、真实 Husky 及提交链路测试(44 项)
199
+ npm run test:integration # Flat Config、真实 Husky 及提交链路测试(55 项)
152
200
  npm run test:legacy:setup # 安装 ESLint 8 隔离运行环境
153
- npm run test:legacy # 运行 ESLint 8.57.0 兼容性回归测试(25 项)
154
- npm run test:all # 全量运行全部 121 项测试
201
+ npm run test:legacy # ESLint 8.57.0 兼容性回归测试(27 项)
202
+ ```
203
+
204
+ `npm run test:all` 由 `scripts/test-all.cjs` 驱动,输出**套件 → 用例 → 汇总**三层:
205
+ 每个大类下面列出它的每条用例(✓/✗/○ + 耗时),最后给出分类统计与总条数。
206
+
207
+ ```text
208
+ my-code-style 测试套件
209
+
210
+ ▶ [1/3] 基础 CLI 与配置矩阵 (共 70 项,5 文件 · 3 文件并发(自动:2 核 / 内存 4G))
211
+ ✓ 运行器 TAP 解析:统计通过与失败、SKIP 与每用例耗时 · 2ms
212
+ ✓ 所有公共导出目标存在且可通过包名解析 · 11ms
213
+ ✓ Prettier 默认值和 JSON/YAML/nvue 文件例外 · 1ms
214
+ …
215
+ ✓ 通过 70 · 2.1s · 最慢文件 init-matrix.test.cjs 1.9s
216
+
217
+ ▶ [2/3] 现代工具链与提交链 (共 55 项,23 文件 · 3 文件并发(自动:2 核 / 内存 4G))
218
+ ✓ 完整提交链:JS/TS/Vue/nvue/CSS/scss 自动修复及二次复检 · 8.0s
219
+ ✓ 完整提交链拦截 nvue 内嵌样式错误(不是仅检查脚本) · 3.6s
220
+ ✓ Flat Config 启用 eslint:recommended 核心规则:no-debugger · 45ms
221
+ …
222
+ ✓ 通过 55 · 30.8s · 最慢文件 commit-chain-both.test.cjs 8.4s
223
+
224
+ ▶ [3/3] ESLint 8 兼容性 (共 27 项,1 文件 · 3 文件并发(自动:2 核 / 内存 4G))
225
+ ✓ ESLint 8 base:生成的 lint 脚本遍历并拦截 broken.ts · 1.1s
226
+ …
227
+ ✓ 通过 27 · 14.3s
228
+
229
+ ──────────────────────────────────────────────────────
230
+ 套件 通过 失败 跳过 用时
231
+ ──────────────────────────────────────────────────────
232
+ 基础 CLI 与配置矩阵 70 0 - 2.1s
233
+ 现代工具链与提交链 55 0 - 30.8s
234
+ ESLint 8 兼容性 27 0 - 14.3s
235
+ ──────────────────────────────────────────────────────
236
+ 合计 152 0 - 47.2s
237
+ ──────────────────────────────────────────────────────
238
+
239
+ ⏱ 最慢文件:eslint8.test.cjs 14.3s · commit-chain-both.test.cjs 8.4s · commit-chain-scss.test.cjs 8.3s
240
+
241
+ ✅ 全部通过:152/152 项,用时 47.2s
155
242
  ```
156
243
 
244
+
245
+
246
+ 终端里每个套件下方还有一条实时进度条(`██████░░░░ 38/66 失败 0 4.0s`)。附加参数:
247
+
248
+ | 参数 | 作用 |
249
+ | -------------------- | ------------------------------------------------------------- |
250
+ | `-- --quiet` | 只看套件结论与汇总表,不列用例明细(长输出时用) |
251
+ | `-- --parallel` | 强制三个套件同时跑(核数 ≥ 8 时默认已自动开启) |
252
+ | `-- --serial` | 强制串行(CI 形态,输出顺序最稳定) |
253
+ | `-- --jobs=2` | 配合并行限制同时运行的套件数,其余排队(面板显示"等待中") |
254
+ | `-- --suite=base,legacy` | 只跑指定套件(base / integration / legacy,逗号分隔) |
255
+ | `-- --concurrency=4` | 覆盖套件内文件级并发(默认按核数与内存自动算,封顶 8) |
256
+ | `-- --verbose` | 展开每个套件的原始 TAP 输出(排查单条用例) |
257
+ | `-- --profile` | 额外列出每个测试文件的耗时(定位集成套件瓶颈时用) |
258
+ | `-- --no-count` | 跳过预统计,进度条退化为"已完成 N 项" |
259
+ | `-- --progress` | 在非 TTY(CI 日志)中也强制刷新进度行 |
260
+
261
+ ### 并行跑更快
262
+
263
+ 测试用例之间不用同一份目录:基础套件只用临时目录,集成套件用 `demo-test/.runtime`,
264
+ ESLint 8 套件用 `demo-test/.runtime-legacy`,所以两层并行都是安全的。**核数 ≥ 8 的机器
265
+ 会自动开启套件级并行**(想固定成 CI 那种串行输出用 `--serial`):
266
+
267
+ 想给本机定一个更合适的并发数,跑 `npm run sweep`:它会把 integration 套件在 auto/1/2/4/6/8/12/16/24 各跑一次,直接给出最快的那一档(并发越高越慢就说明瓶颈在进程启动而非 CPU)。
268
+
269
+ 换了机器发现某个套件特别慢?先跑 `npm run diagnose`:它会把「进程启动 / npx 开销 / git / 文件系统 / 一次真实提交的 hooks」逐项列出来,直接指出时间花在哪一层。
270
+
271
+ ```bash
272
+ npm run test:all # 16 核机器:自动并行,墙钟 ≈ 最慢的那套
273
+ npm run test:all -- --serial # 强制串行
274
+ npm run test:all -- --parallel # 低核机器上强制并行
275
+ npm run test:all -- --profile # 看每个测试文件耗时,定位瓶颈
276
+ ```
277
+
278
+ 两层并行的实现:
279
+
280
+ - **文件级**:集成套件按"一条提交链一个文件"拆成 23 个测试文件,**由运行器自己按文件
281
+ 调度**(每个文件一个 `node --test` 进程),不依赖 Node 的 `--test` 默认并发值——
282
+ 同一个文件内的用例仍然串行(真实 git 仓库不能并行改),文件之间才是并发的。
283
+ - **套件级**:三个套件再并行,互不共享目录。
284
+
285
+ 因为每个文件里跑的都是真实 `git commit`(单次 0.5–3.9s),墙钟由**最慢的那个文件**
286
+ 决定,所以文件尽量拆到"一个文件一次提交"。每个套件跑完会直接告诉你最慢文件是谁,
287
+ 汇总区再给一次全局 `⏱ 最慢文件`:
288
+
289
+ | integration 子文件(23 个) | 单文件耗时(2 核、串行) | 内容 |
290
+ | -------------------------- | ---------------------- | ---- |
291
+ | `commit-chain-{scss,less,both}` | 2.7–3.3s | 三种预处理器的完整提交链(各 1 次提交) |
292
+ | `empty-commit-guard` | 2.7s | 空提交守卫(重复暂存不得产生漂移提交) |
293
+ | `git-mv-rm` | 3.2s | `git mv` / `git rm` 走 lint-staged |
294
+ | `embedded-style-{vue,nvue,mixed-less}` | 1.9–2.0s | Vue/nvue 内嵌样式错误拦截 |
295
+ | `git-edge-{first-commit,stash}` | 2.1s / 1.7s | 首次提交、用户 stash 保留 |
296
+ | `partial-staging{,-unstaged,-invalid-message,-conflict}` | 0.5–1.7s | 部分暂存与冲突恢复 |
297
+ | `error-recovery-{css,scss,less,js,ts,vue,nvue}` | 0.5–1.4s | 不可修复错误的回滚 |
298
+ | `lint` | 3.9s | 32 条规则与格式化行为(无提交链) |
299
+ | `release` | 0.8s | standard-version |
300
+
301
+ 两层并发都要控制规模,所以默认并发不交给 Node 猜,而是运行器自己算——**核数 × 1.5
302
+ (至少 核数 - 1),再乘内存上限,最后封顶 8**(16 核机器实测:4/6/8/12/16/24 并发对应
303
+ 20.3/18.7/19.0/19.2/18.9/19.1s,6–8 之后加并发只会让每个文件变慢;要更多用
304
+ `--concurrency` 覆盖):实测一条真实提交链(`git` + `npx` + `eslint` +
305
+ `prettier`)峰值 RSS 约 0.8GB,运行器留 30% 内存给系统,避免并发过多的小内存机器被
306
+ 并发 git/npx 撑到 OOM(进程被 SIGKILL);文件数多于并发数时,**用例少的文件(多半是同
307
+ 一条重链)优先开跑**,避免长任务被排进最后一波、墙钟再多乘一倍。
308
+
309
+ 实测(2 核沙箱,152 项;沙箱内存 4G,所以自动并发是 3):
310
+
311
+ | 运行方式 | 墙钟时间 |
312
+ | ----------------------------------- | ----------------------------------------------- |
313
+ | 串行套件 + 文件级并发 1(CI 旧形态) | 62.4s(hook 改造前同配置 70.3s) |
314
+ | 串行套件 + 自动并发 3(默认) | 47.2s(hook 改造前同配置 51.8s) |
315
+ | `--parallel` 三套件 + 自动并发 3 | 43.0s(hook 改造前同配置 46.6s) |
316
+ | `node --test demo-test/integration/*.test.cjs`(Node 自己调度,等同旧命令) | 43.7s(只看集成套件那一段) |
317
+ | `npm run test:integration`(运行器调度,自动并发 3) | 30.6s(只看集成套件那一段) |
318
+ | 串行套件 + 文件级并发 23(全部一波) | ✗ 3.8G 内存沙箱被 OOM 压垮(19 项 SIGKILL) |
319
+
320
+ (2 核沙箱里并行收益被 CPU 争抢吃掉大半,`--concurrency=1` 时单个文件只要 0.7–4.2s;
321
+ 16 核机器上集成套件那段 ≈ 最慢子文件,即"一次真实提交"的量级。)
322
+ 生成的 hook 优先直连本地 bin(husky 已把 `node_modules/.bin` 放进 PATH),
323
+ 找不到时才退回 `npx --no-install`——每次提交因此少起两个 npm CLI(实测每个 hook
324
+ 省 130–185ms),提交链从 3.3s 降到 2.8s。集成 fixture 同样用环境变量传 git 身份
325
+ (`GIT_AUTHOR_*` / `GIT_CONFIG_COUNT`)代替 4 次 `git config`。
326
+
327
+ `demo-test/integration/_runtime.cjs` 用「指纹 + 目录锁」保证并发启动时只同步一次
328
+ 隔离环境源码,不会读到写了一半的文件;`prettier` / `eslint` 以 getter 惰性加载,
329
+ 只做提交链的 8 个文件不再为它们付启动开销。
330
+
331
+ 未安装隔离运行环境时,对应套件会明确标记"未运行"并给出 setup 命令,退出码为 1(不会假装全绿)。
332
+
157
333
  ## License
158
334
 
159
335
  MIT