my-code-style 1.9.0 → 1.9.1

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 CHANGED
@@ -1,5 +1,12 @@
1
1
  ## 变更日志
2
2
 
3
+ ## [1.9.1](https://github.com/myvn/codeStyle/compare/v1.9.0...v1.9.1) (2026-09-23)
4
+
5
+ ### 🐛 Bug Fixes | Bug 修复
6
+
7
+ - **doctor:** ESM-only peer 误报未安装——版本探测改文件系统链优先 ([418aeb5](https://github.com/myvn/codeStyle/commit/418aeb5c90b097719a37aa96ee9bf140a4550b45))
8
+ - **init:** --merge 统计语义「保留/覆盖」对齐 + 新增 lint:style 全量样式入口 ([9ebe796](https://github.com/myvn/codeStyle/commit/9ebe796b7959052c1880af1af164247abcc16a98))
9
+
3
10
  ## [1.9.0](https://github.com/myvn/codeStyle/compare/v1.8.6...v1.9.0) (2026-09-23)
4
11
 
5
12
  ### ✨ Features | 新功能
package/README.md CHANGED
@@ -204,6 +204,16 @@ npx my-code-style-init [--dry-run] [--backup] [--merge] [--version|-v] [--help|-
204
204
  - 初始化结束时**自动自检 hooks**(存在 / 非空 / 可执行位 / `lint-staged`、`commitlint` 是否可解析),只提示不阻断——把"hook 存在但不生效"消灭在当场。
205
205
  - 具备**事务回滚保护**:若在写入过程中遭遇文件权限或磁盘异常,自动回滚所有修改,恢复工作区原始状态。
206
206
 
207
+ ## lint 覆盖范围须知
208
+
209
+ `lint` 脚本只跑 **ESLint**;Stylelint 默认只在 pre-commit 的 lint-staged 里对**本次改动的文件**执行。CI 如果只跑 `pnpm lint`,CSS/SCSS/Vue 内嵌样式不会被检查。有 CSS 预处理器的项目,init 会额外生成全量样式检查入口:
210
+
211
+ ```bash
212
+ pnpm lint:style # stylelint "**/*.{vue,nvue,html,css,scss,less}"
213
+ ```
214
+
215
+ 把 `lint:style` 加进 CI(或并进 `lint:all`)即可补齐覆盖面。
216
+
207
217
  ## 项目体检:my-code-style-doctor
208
218
 
209
219
  ```bash
@@ -258,10 +268,10 @@ npx my-code-style-doctor
258
268
  ## 测试套件
259
269
 
260
270
  ```bash
261
- npm run test:all # 全量运行 194 项:用例明细 + 分类统计 + 最慢文件定位
271
+ npm run test:all # 全量运行 197 项:用例明细 + 分类统计 + 最慢文件定位
262
272
  npm run diagnose # 换机器后先跑它:进程 / git / 文件系统 / hooks 各占多少
263
273
  npm run sweep # 给本机找最佳文件级并发(扫 integration 套件)
264
- npm test # 只跑基础 CLI 与配置矩阵(93 项)
274
+ npm test # 只跑基础 CLI 与配置矩阵(96 项)
265
275
  npm run test:integration:setup # 安装现代化隔离依赖运行环境
266
276
  npm run test:integration # Flat Config、真实 Husky 及提交链路测试(65 项)
267
277
  npm run test:legacy:setup # 安装 ESLint 8 隔离运行环境
@@ -276,47 +286,47 @@ npm run test:stylelint17 # Stylelint 17 生态兼容性回归(8 项)
276
286
  ```text
277
287
  my-code-style 测试套件
278
288
 
279
- ▶ [1/4] 基础 CLI 与配置矩阵 (共 93 项,5 文件 · 3 文件并发(自动:2 核 / 内存 4G))
289
+ ▶ [1/4] 基础 CLI 与配置矩阵 (共 96 项,5 文件 · 3 文件并发(自动:2 核 / 内存 4G))
280
290
  ✓ 运行器 TAP 解析:统计通过与失败、SKIP 与每用例耗时 · 7ms
281
291
  ✓ cz 交互提示为中文,且可选类型与 type-enum 一一对应 · 1ms
282
292
  ✓ peer 范围覆盖我们声明支持的上游大版本(校准防回退,BUG-027) · 0ms
283
293
  ✓ 一键安装命令对含 || 的版本范围加引号,可整段粘贴执行 · 40ms
284
294
  ✓ 初始化结尾指引把 cz 用法说清楚(先 git add + 指到 README 手册) · 80ms
285
295
  …
286
- ✓ 通过 93 · 4.9s · 最慢文件 init-matrix.test.cjs 4.6s
296
+ ✓ 通过 96 · 3.6s · 最慢文件 init-matrix.test.cjs 3.4s
287
297
 
288
298
  ▶ [2/4] 现代工具链与提交链 (共 65 项,24 文件 · 3 文件并发(自动:2 核 / 内存 4G))
289
299
  ✓ 完整提交链:JS/TS/Vue/nvue/CSS/less 自动修复及二次复检 · 10.4s
290
300
  ✓ 发布防呆:HEAD 已有 v* tag 时拦截(此时 release 工具会静默抬版并写出空 CHANGELOG) · 609ms
291
301
  …
292
- ✓ 通过 65 · 50.7s · 最慢文件 commit-chain-both.test.cjs 16.1s
302
+ ✓ 通过 65 · 39.5s · 最慢文件 commit-chain-scss.test.cjs 12.7s
293
303
 
294
304
  ▶ [3/4] ESLint 8 兼容性 (共 27 项,1 文件 · 3 文件并发(自动:2 核 / 内存 4G))
295
305
  ✓ 独立运行 ESLint 8 支持下限而非 ESLint 9 · 1ms
296
306
  ✓ ESLint 8 base:实际 CLI 加载生成配置并接受正常文件 · 1.3s
297
307
  …
298
- ✓ 通过 27 · 19.4s
308
+ ✓ 通过 27 · 16.3s
299
309
 
300
310
  ▶ [4/4] Stylelint 17 兼容性 (共 9 项,1 文件 · 3 文件并发(自动:2 核 / 内存 4G))
301
311
  ✓ 隔离环境装的是 stylelint 17(不是 16) · 2ms
302
312
  ✓ 生成的 .stylelintrc.cjs 在 stylelint 17 下可加载并放过正常 SCSS · 700ms
303
313
  …
304
- ✓ 通过 9 · 9.6s
314
+ ✓ 通过 9 · 7.4s
305
315
 
306
316
  ──────────────────────────────────────────────────────
307
317
  套件 通过 失败 跳过 用时
308
318
  ──────────────────────────────────────────────────────
309
- 基础 CLI 与配置矩阵 93 0 - 4.9s
310
- 现代工具链与提交链 65 0 - 50.7s
311
- ESLint 8 兼容性 27 0 - 19.4s
312
- Stylelint 17 兼容性 9 0 - 9.6s
319
+ 基础 CLI 与配置矩阵 96 0 - 3.6s
320
+ 现代工具链与提交链 65 0 - 39.5s
321
+ ESLint 8 兼容性 27 0 - 16.3s
322
+ Stylelint 17 兼容性 9 0 - 7.4s
313
323
  ──────────────────────────────────────────────────────
314
- 合计 194 0 - 84.6s
324
+ 合计 197 0 - 66.8s
315
325
  ──────────────────────────────────────────────────────
316
326
 
317
327
  ⏱ 最慢文件:eslint8.test.cjs 18.0s · commit-chain-less.test.cjs 11.4s · commit-chain-both.test.cjs 11.3s
318
328
 
319
- ✅ 全部通过:194/194 项,用时 84.6s
329
+ ✅ 全部通过:197/197 项,用时 66.8s
320
330
  ```
321
331
 
322
332
  终端里每个套件下方还有一条实时进度条(`██████░░░░ 38/66 失败 0 4.0s`)。附加参数:
@@ -394,7 +404,7 @@ npm run test:all -- --profile # 看每个测试文件耗时,定位瓶颈
394
404
  | `npm run test:integration`(运行器调度,自动并发 3) | 30.6s(只看集成套件那一段) |
395
405
  | 串行套件 + 文件级并发 23(全部一波) | ✗ 3.8G 内存沙箱被 OOM 压垮(19 项 SIGKILL) |
396
406
 
397
- 同机复测(194 项,同一台 2 核沙箱连续跑;绝对秒数随机器负载波动,相对关系稳定):默认自动并发 3 = 84.6s、`npm run test:integration` = 50.7s(本轮实跑;串行与 parallel 口径为早前基线实测,相对关系稳定)。
407
+ 同机复测(197 项,同一台 2 核沙箱连续跑;绝对秒数随机器负载波动,相对关系稳定):默认自动并发 3 = 66.8s、`npm run test:integration` = 39.5s(本轮实跑;串行与 parallel 口径为早前基线实测,相对关系稳定)。
398
408
 
399
409
  (2 核沙箱里并行收益被 CPU 争抢吃掉大半,`--concurrency=1` 时单个文件只要 0.7–4.2s;
400
410
  16 核机器上集成套件那段 ≈ 最慢子文件,即"一次真实提交"的量级。)
package/bin/doctor CHANGED
@@ -55,15 +55,36 @@ function readManifest() {
55
55
  }
56
56
  }
57
57
 
58
- // 读取依赖包版本:优先裸包名/package.json(可能被 exports 挡,如 less),
59
- // 回退到 resolve(裸包名) 后读相邻 package.json
58
+ // 从 startDir 逐级向上直读 node_modules/<name>/package.json(纯文件系统,不经过
59
+ // 模块解析)。必须走这条路:ESM-only 包(如 stylelint-config-recommended@18,
60
+ // 下游 1.9.0 实测 BUG-035)的 exports 常常只有 "import" 条件且不暴露
61
+ // "./package.json",CJS require/resolve 双双抛 ERR_PACKAGE_PATH_NOT_EXPORTED,
62
+ // 曾被误判为"未安装"。读文件天然兼容 ESM-only / exports 任意形态 / pnpm 符号链接。
63
+ function findPkgUp(startDir, name) {
64
+ let cur = startDir
65
+ while (true) {
66
+ try {
67
+ return JSON.parse(
68
+ fs.readFileSync(path.join(cur, "node_modules", name, "package.json"), "utf8"),
69
+ )
70
+ } catch {}
71
+ const parent = path.dirname(cur)
72
+ if (parent === cur) return null
73
+ cur = parent
74
+ }
75
+ }
76
+
77
+ // 读取依赖包版本:文件系统链优先, exotic 布局回退模块解析
60
78
  function installedVersion(projectRequire, name) {
79
+ // ① 项目根向上(标准安装);② 本脚本位置向上(npx 临时目录 / monorepo hoisting /
80
+ // pnpm 内部 .pnpm 的真实包经符号链接可达)
81
+ const direct = findPkgUp(PROJECT_ROOT, name) ?? findPkgUp(__dirname, name)
82
+ if (direct?.version) return direct.version
61
83
  try {
62
84
  return require(`${name}/package.json`).version
63
85
  } catch {}
64
86
  try {
65
87
  const entry = projectRequire.resolve(name)
66
- // 截掉入口文件取包目录(用 path.dirname;别用正则截第一个分隔符——会得到空串)
67
88
  const dir = path.dirname(entry)
68
89
  return JSON.parse(fs.readFileSync(path.join(dir, "package.json"), "utf8")).version
69
90
  } catch {
package/bin/init CHANGED
@@ -926,10 +926,13 @@ function main() {
926
926
  stepHeader(3, 6, "配置文件与 Git hooks")
927
927
  let overwriteTotal = 0
928
928
  let createTotal = 0
929
+ // --merge 下"已存在"的语义是保留而非覆盖,统计与文案必须一致,
930
+ // 否则预览先吓唬人、写入段再改口"保留",前后矛盾(下游 1.9.0 实测)
931
+ const verb = mergeMode ? "保留" : "覆盖"
929
932
  for (const f of files) {
930
933
  if (f.exists) {
931
934
  overwriteTotal++
932
- console.log(` 覆盖 ${f.path}`)
935
+ console.log(` ${verb} ${f.path}`)
933
936
  } else {
934
937
  createTotal++
935
938
  console.log(` 新建 ${f.path}`)
@@ -951,7 +954,7 @@ function main() {
951
954
  for (const h of hooks) {
952
955
  if (fileExists(h.path)) {
953
956
  overwriteTotal++
954
- console.log(` 覆盖 ${h.path}`)
957
+ console.log(` ${verb} ${h.path}`)
955
958
  } else {
956
959
  createTotal++
957
960
  console.log(` 新建 ${h.path}`)
@@ -959,7 +962,7 @@ function main() {
959
962
  }
960
963
 
961
964
  console.log(
962
- ` 小计:覆盖 ${overwriteTotal} 个 · 新建 ${createTotal} 个` +
965
+ ` 小计:${verb} ${overwriteTotal} 个 · 新建 ${createTotal} 个` +
963
966
  (backup ? " · 旧文件将备份到 .my-code-style-backup/" : "") +
964
967
  (dryRun ? "(Dry run 预览,不写入)" : ""),
965
968
  )
@@ -1017,7 +1020,7 @@ function main() {
1017
1020
  success("Dry run 结束:未写入任何文件;去掉 --dry-run 执行真实初始化")
1018
1021
  } else {
1019
1022
  success(
1020
- `初始化完成:覆盖 ${overwriteTotal} 个 · 新建 ${createTotal} 个 · package.json 已更新`,
1023
+ `初始化完成:${verb} ${overwriteTotal} 个 · 新建 ${createTotal} 个 · package.json 已更新`,
1021
1024
  )
1022
1025
  }
1023
1026
  console.log("")
@@ -1125,7 +1128,6 @@ function main() {
1125
1128
  // Actually write files
1126
1129
  for (const f of files) {
1127
1130
  if (mergeMode && snapshot.get(f.path)?.existed) {
1128
- console.log(` · 保留 ${f.path}(--merge 不覆盖)`)
1129
1131
  continue
1130
1132
  }
1131
1133
  writeFile(f.path, f.content)
@@ -1137,7 +1139,6 @@ function main() {
1137
1139
  }
1138
1140
  for (const h of hooks) {
1139
1141
  if (mergeMode && snapshot.get(h.path)?.existed) {
1140
- console.log(` · 保留 ${h.path}(--merge 不覆盖)`)
1141
1142
  continue
1142
1143
  }
1143
1144
  writeFile(h.path, h.content)
@@ -1150,6 +1151,12 @@ function main() {
1150
1151
  scripts: {
1151
1152
  lint: lintCommand,
1152
1153
  "lint:fix": `${lintCommand} --fix`,
1154
+ // CI 只跑 pnpm lint 时会漏检 CSS(下游 1.9.0 反馈):给有
1155
+ // 预处理器的项目一个全量 stylelint 入口;ignoreFiles 已在
1156
+ // 配置里排除 node_modules/dist 等,glob 全仓是安全的
1157
+ ...(skipStylelint
1158
+ ? {}
1159
+ : { "lint:style": 'stylelint "**/*.{vue,nvue,html,css,scss,less}"' }),
1153
1160
  format: "prettier --write .",
1154
1161
  prepare: "husky",
1155
1162
  release: "commit-and-tag-version",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "my-code-style",
3
- "version": "1.9.0",
3
+ "version": "1.9.1",
4
4
  "description": "Lint/Format/Git 配置工程化 npm 包(ESLint + Prettier + Stylelint + Commitlint + Husky + standard-version)",
5
5
  "type": "commonjs",
6
6
  "main": "src/eslint/uniapp.cjs",