my-code-style 1.8.0 → 1.8.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 +12 -0
- package/README.md +22 -22
- package/bin/init +153 -83
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
## 变更日志
|
|
2
2
|
|
|
3
|
+
### [1.8.1](https://github.com/myvn/codeStyle/compare/v1.8.0...v1.8.1) (2026-09-20)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### 🐛 Bug Fixes | Bug 修复
|
|
7
|
+
|
|
8
|
+
* **init:** 安装命令里的版本范围加引号,粘贴不再被 shell 截断 ([9abaf1d](https://github.com/myvn/codeStyle/commit/9abaf1d76ea3aff05f0d26d11a43e8661ed6221a))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### ✨ Features | 新功能
|
|
12
|
+
|
|
13
|
+
* **init:** 输出步骤化为固定六步,dry-run 全流程预览 ([f14ca47](https://github.com/myvn/codeStyle/commit/f14ca47449b7d3e8f9a381b6e145e99232586886))
|
|
14
|
+
|
|
3
15
|
## [1.8.0](https://github.com/myvn/codeStyle/compare/v1.7.2...v1.8.0) (2026-09-20)
|
|
4
16
|
|
|
5
17
|
### ✨ Features | 新功能
|
package/README.md
CHANGED
|
@@ -239,10 +239,10 @@ npx my-code-style-init [--dry-run] [--backup] [--version|-v] [--help|-h]
|
|
|
239
239
|
## 测试套件
|
|
240
240
|
|
|
241
241
|
```bash
|
|
242
|
-
npm run test:all # 全量运行
|
|
242
|
+
npm run test:all # 全量运行 178 项:用例明细 + 分类统计 + 最慢文件定位
|
|
243
243
|
npm run diagnose # 换机器后先跑它:进程 / git / 文件系统 / hooks 各占多少
|
|
244
244
|
npm run sweep # 给本机找最佳文件级并发(扫 integration 套件)
|
|
245
|
-
npm test # 只跑基础 CLI 与配置矩阵(
|
|
245
|
+
npm test # 只跑基础 CLI 与配置矩阵(84 项)
|
|
246
246
|
npm run test:integration:setup # 安装现代化隔离依赖运行环境
|
|
247
247
|
npm run test:integration # Flat Config、真实 Husky 及提交链路测试(59 项)
|
|
248
248
|
npm run test:legacy:setup # 安装 ESLint 8 隔离运行环境
|
|
@@ -257,46 +257,46 @@ npm run test:stylelint17 # Stylelint 17 生态兼容性回归(8 项)
|
|
|
257
257
|
```text
|
|
258
258
|
my-code-style 测试套件
|
|
259
259
|
|
|
260
|
-
▶ [1/4] 基础 CLI 与配置矩阵 (共
|
|
261
|
-
✓ 运行器 TAP 解析:统计通过与失败、SKIP 与每用例耗时 ·
|
|
262
|
-
✓ 运行器表格:CJK 宽度按两列计算,耗时格式化区分秒与毫秒 · 1ms
|
|
260
|
+
▶ [1/4] 基础 CLI 与配置矩阵 (共 84 项,5 文件 · 3 文件并发(自动:2 核 / 内存 4G))
|
|
261
|
+
✓ 运行器 TAP 解析:统计通过与失败、SKIP 与每用例耗时 · 7ms
|
|
263
262
|
✓ cz 交互提示为中文,且可选类型与 type-enum 一一对应 · 1ms
|
|
264
|
-
✓
|
|
263
|
+
✓ 一键安装命令对含 || 的版本范围加引号,可整段粘贴执行 · 44ms
|
|
264
|
+
✓ 初始化结尾指引把 cz 用法说清楚(先 git add + 指到 README 手册) · 80ms
|
|
265
265
|
…
|
|
266
|
-
✓ 通过
|
|
266
|
+
✓ 通过 84 · 3.5s · 最慢文件 init-matrix.test.cjs 3.2s
|
|
267
267
|
|
|
268
268
|
▶ [2/4] 现代工具链与提交链 (共 59 项,23 文件 · 3 文件并发(自动:2 核 / 内存 4G))
|
|
269
|
-
✓ 完整提交链:JS/TS/Vue/nvue/CSS/less 自动修复及二次复检 · 10.
|
|
270
|
-
✓ 发布防呆:HEAD 已有 v* tag 时拦截(此时 standard-version 会静默抬版并写出空 CHANGELOG) ·
|
|
269
|
+
✓ 完整提交链:JS/TS/Vue/nvue/CSS/less 自动修复及二次复检 · 10.4s
|
|
270
|
+
✓ 发布防呆:HEAD 已有 v* tag 时拦截(此时 standard-version 会静默抬版并写出空 CHANGELOG) · 609ms
|
|
271
271
|
…
|
|
272
|
-
✓ 通过 59 · 41.
|
|
272
|
+
✓ 通过 59 · 41.0s · 最慢文件 commit-chain-both.test.cjs 10.6s
|
|
273
273
|
|
|
274
274
|
▶ [3/4] ESLint 8 兼容性 (共 27 项,1 文件 · 3 文件并发(自动:2 核 / 内存 4G))
|
|
275
275
|
✓ 独立运行 ESLint 8 支持下限而非 ESLint 9 · 1ms
|
|
276
|
-
✓ ESLint 8 base:实际 CLI 加载生成配置并接受正常文件 · 1.
|
|
276
|
+
✓ ESLint 8 base:实际 CLI 加载生成配置并接受正常文件 · 1.3s
|
|
277
277
|
…
|
|
278
|
-
✓ 通过 27 ·
|
|
278
|
+
✓ 通过 27 · 18.3s
|
|
279
279
|
|
|
280
280
|
▶ [4/4] Stylelint 17 兼容性 (共 8 项,1 文件 · 3 文件并发(自动:2 核 / 内存 4G))
|
|
281
281
|
✓ 隔离环境装的是 stylelint 17(不是 16) · 2ms
|
|
282
|
-
✓ 生成的 .stylelintrc.cjs 在 stylelint 17 下可加载并放过正常 SCSS ·
|
|
282
|
+
✓ 生成的 .stylelintrc.cjs 在 stylelint 17 下可加载并放过正常 SCSS · 700ms
|
|
283
283
|
…
|
|
284
|
-
✓ 通过 8 · 7.
|
|
284
|
+
✓ 通过 8 · 7.2s
|
|
285
285
|
|
|
286
286
|
──────────────────────────────────────────────────────
|
|
287
287
|
套件 通过 失败 跳过 用时
|
|
288
288
|
──────────────────────────────────────────────────────
|
|
289
|
-
基础 CLI 与配置矩阵
|
|
290
|
-
现代工具链与提交链 59 0 - 41.
|
|
291
|
-
ESLint 8 兼容性 27 0 -
|
|
292
|
-
Stylelint 17 兼容性 8 0 - 7.
|
|
289
|
+
基础 CLI 与配置矩阵 84 0 - 3.5s
|
|
290
|
+
现代工具链与提交链 59 0 - 41.0s
|
|
291
|
+
ESLint 8 兼容性 27 0 - 18.3s
|
|
292
|
+
Stylelint 17 兼容性 8 0 - 7.2s
|
|
293
293
|
──────────────────────────────────────────────────────
|
|
294
|
-
合计
|
|
294
|
+
合计 178 0 - 81.3s
|
|
295
295
|
──────────────────────────────────────────────────────
|
|
296
296
|
|
|
297
|
-
⏱ 最慢文件:eslint8.test.cjs
|
|
297
|
+
⏱ 最慢文件:eslint8.test.cjs 18.3s · commit-chain-both.test.cjs 10.6s · commit-chain-scss.test.cjs 10.6s
|
|
298
298
|
|
|
299
|
-
✅ 全部通过:
|
|
299
|
+
✅ 全部通过:178/178 项,用时 81.3s
|
|
300
300
|
```
|
|
301
301
|
|
|
302
302
|
终端里每个套件下方还有一条实时进度条(`██████░░░░ 38/66 失败 0 4.0s`)。附加参数:
|
|
@@ -374,7 +374,7 @@ npm run test:all -- --profile # 看每个测试文件耗时,定位瓶颈
|
|
|
374
374
|
| `npm run test:integration`(运行器调度,自动并发 3) | 30.6s(只看集成套件那一段) |
|
|
375
375
|
| 串行套件 + 文件级并发 23(全部一波) | ✗ 3.8G 内存沙箱被 OOM 压垮(19 项 SIGKILL) |
|
|
376
376
|
|
|
377
|
-
同机复测(
|
|
377
|
+
同机复测(178 项,同一台 2 核沙箱连续跑;绝对秒数随机器负载波动,相对关系稳定):串行套件 + 文件级并发 1 = 70.3s、默认自动并发 3 = 81.3s、`--parallel` 四套件 = 59.1s、`npm run test:integration` = 41.5s、`node --test demo-test/integration/*.test.cjs` = 58.4s(后四项为 177 项时实测,仅基础套件 +2 用例,差值在秒级)。
|
|
378
378
|
|
|
379
379
|
(2 核沙箱里并行收益被 CPU 争抢吃掉大半,`--concurrency=1` 时单个文件只要 0.7–4.2s;
|
|
380
380
|
16 核机器上集成套件那段 ≈ 最慢子文件,即"一次真实提交"的量级。)
|
package/bin/init
CHANGED
|
@@ -65,7 +65,6 @@ function ensureGitignoreEntry(entry) {
|
|
|
65
65
|
`${content}${separator}\n# my-code-style 初始化备份目录\n${entry}\n`,
|
|
66
66
|
"utf8",
|
|
67
67
|
)
|
|
68
|
-
log(`已将 ${entry} 追加到 .gitignore`)
|
|
69
68
|
}
|
|
70
69
|
|
|
71
70
|
function getProjectPkg() {
|
|
@@ -431,6 +430,28 @@ function addDevCommand(packageManager) {
|
|
|
431
430
|
}
|
|
432
431
|
}
|
|
433
432
|
|
|
433
|
+
// 步骤标题行:CJK 字符按 2 列计宽,右侧补齐横线,让每个步骤标题线等长
|
|
434
|
+
function displayWidth(text) {
|
|
435
|
+
let width = 0
|
|
436
|
+
for (const ch of text) {
|
|
437
|
+
width += ch.codePointAt(0) > 0xff ? 2 : 1
|
|
438
|
+
}
|
|
439
|
+
return width
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
function stepHeader(current, total, title) {
|
|
443
|
+
const head = `步骤 ${current}/${total} · ${title}`
|
|
444
|
+
const pad = Math.max(4, 46 - displayWidth(head))
|
|
445
|
+
console.log(`\n ── ${head} ${"─".repeat(pad)}`)
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// 打印安装规格时按需加引号:`name@range` 里含 || 或 >= 等字符会被 shell 当成
|
|
449
|
+
// 管道/重定向,把整条命令截断(stylelint@^16.24.0 || ^17.0.0 原样粘贴必炸)。
|
|
450
|
+
// 规格含安全字符集(字母数字 @ / . _ ^ ~ -)之外的任何字符就整体包一层双引号。
|
|
451
|
+
function shellSafeSpec(spec) {
|
|
452
|
+
return /[^A-Za-z0-9@/._^~-]/.test(spec) ? `"${spec}"` : spec
|
|
453
|
+
}
|
|
454
|
+
|
|
434
455
|
/**
|
|
435
456
|
* `pnpm prepare` / `yarn prepare` run the script directly, but npm needs an
|
|
436
457
|
* explicit `npm run prepare` (plain `npm prepare` is not a command).
|
|
@@ -712,15 +733,17 @@ function main() {
|
|
|
712
733
|
}
|
|
713
734
|
|
|
714
735
|
const dryRun = process.argv.includes("--dry-run")
|
|
715
|
-
const label = dryRun ? "[DRY RUN] " : ""
|
|
716
736
|
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
737
|
+
let toolVersion = ""
|
|
738
|
+
try {
|
|
739
|
+
toolVersion = ` v${require("../package.json").version}`
|
|
740
|
+
} catch {}
|
|
720
741
|
|
|
742
|
+
console.log("")
|
|
743
|
+
console.log(` my-code-style-init${toolVersion} — 把 my-code-style 接入当前项目`)
|
|
721
744
|
if (dryRun) {
|
|
722
|
-
warn("Dry run mode — no files will be written")
|
|
723
745
|
console.log("")
|
|
746
|
+
warn("Dry run 预览模式:以下所有步骤都不会写入文件")
|
|
724
747
|
}
|
|
725
748
|
|
|
726
749
|
// --- Detection phase ---
|
|
@@ -752,11 +775,7 @@ function main() {
|
|
|
752
775
|
return
|
|
753
776
|
}
|
|
754
777
|
|
|
755
|
-
|
|
756
|
-
warn(
|
|
757
|
-
`ESLint ${eslintVersion} 尚未在 peerDependencies 声明支持(^8.57.0 || ^9.0.0 || ^10.0.0),将按 Flat Config 生成`,
|
|
758
|
-
)
|
|
759
|
-
}
|
|
778
|
+
const eslintUnannounced = eslintVersion !== null && eslintVersion > 10
|
|
760
779
|
|
|
761
780
|
// Do not silently mix an installed major version with an incompatible format.
|
|
762
781
|
if (
|
|
@@ -777,21 +796,32 @@ function main() {
|
|
|
777
796
|
const useFlatConfig = eslintVersion !== 8
|
|
778
797
|
const eslintFormat = useFlatConfig ? "flat" : "eslintrc"
|
|
779
798
|
|
|
780
|
-
|
|
781
|
-
log(
|
|
782
|
-
|
|
799
|
+
stepHeader(1, 6, "检测项目环境")
|
|
800
|
+
console.log(` · 包管理器:${pm}`)
|
|
801
|
+
console.log(
|
|
802
|
+
` · ESLint:${eslintVersion || "未声明,按已安装版本处理"} → ${eslintFormat === "flat" ? "Flat Config" : "传统 .eslintrc 格式"}`,
|
|
783
803
|
)
|
|
784
|
-
log(
|
|
785
|
-
|
|
804
|
+
console.log(
|
|
805
|
+
` · 项目类型:${projectType === "uniapp" ? "uni-app" : projectType === "vue" ? "Vue" : "Node/TS 基础库"}`,
|
|
786
806
|
)
|
|
787
|
-
console.log(
|
|
807
|
+
console.log(
|
|
808
|
+
` · CSS 预处理器:${cssPreprocessor === "both" ? "SCSS + Less(混合)" : cssPreprocessor === "none" ? "未检测到" : cssPreprocessor}`,
|
|
809
|
+
)
|
|
810
|
+
if (eslintUnannounced) {
|
|
811
|
+
warn(
|
|
812
|
+
`ESLint ${eslintVersion} 尚未在 peerDependencies 声明支持(^8.57.0 || ^9.0.0 || ^10.0.0),将按 Flat Config 生成`,
|
|
813
|
+
)
|
|
814
|
+
}
|
|
788
815
|
|
|
789
816
|
// --- Build file list based on detection ---
|
|
790
817
|
const files = []
|
|
818
|
+
let skipStylelint = false
|
|
791
819
|
|
|
820
|
+
stepHeader(2, 6, "ESLint 入口")
|
|
792
821
|
if (hasFlatConfigFile || hasLegacyConfigFile) {
|
|
793
|
-
log("保留已有 ESLint 配置,不生成额外入口")
|
|
822
|
+
console.log(" 保留已有 ESLint 配置,不生成额外入口")
|
|
794
823
|
} else if (useFlatConfig) {
|
|
824
|
+
console.log(" 生成 Flat Config 入口 eslint.config.mjs")
|
|
795
825
|
files.push({
|
|
796
826
|
path: "eslint.config.mjs",
|
|
797
827
|
exists:
|
|
@@ -802,6 +832,7 @@ function main() {
|
|
|
802
832
|
content: eslintFlatConfigContent(projectType),
|
|
803
833
|
})
|
|
804
834
|
} else {
|
|
835
|
+
console.log(" 生成传统格式入口 .eslintrc.cjs")
|
|
805
836
|
files.push({
|
|
806
837
|
path: ".eslintrc.cjs",
|
|
807
838
|
exists: fileExists(".eslintrc.cjs"),
|
|
@@ -829,7 +860,7 @@ function main() {
|
|
|
829
860
|
content: stylelintrcContent(cssPreprocessor),
|
|
830
861
|
})
|
|
831
862
|
} else {
|
|
832
|
-
|
|
863
|
+
skipStylelint = true
|
|
833
864
|
}
|
|
834
865
|
|
|
835
866
|
files.push({
|
|
@@ -844,11 +875,7 @@ function main() {
|
|
|
844
875
|
versionrcPath = ".versionrc.cjs"
|
|
845
876
|
}
|
|
846
877
|
|
|
847
|
-
|
|
848
|
-
warn(
|
|
849
|
-
"检测到 ESM 项目 (type: module) 存在旧的 .versionrc.js,standard-version 需使用 .versionrc.cjs",
|
|
850
|
-
)
|
|
851
|
-
}
|
|
878
|
+
const staleVersionrc = isEsm && fileExists(".versionrc.js") && !fileExists(".versionrc.cjs")
|
|
852
879
|
|
|
853
880
|
files.push({
|
|
854
881
|
path: versionrcPath,
|
|
@@ -876,12 +903,17 @@ function main() {
|
|
|
876
903
|
})
|
|
877
904
|
}
|
|
878
905
|
|
|
879
|
-
|
|
906
|
+
const backup = args.includes("--backup")
|
|
907
|
+
stepHeader(3, 6, "配置文件与 Git hooks")
|
|
908
|
+
let overwriteTotal = 0
|
|
909
|
+
let createTotal = 0
|
|
880
910
|
for (const f of files) {
|
|
881
911
|
if (f.exists) {
|
|
882
|
-
|
|
912
|
+
overwriteTotal++
|
|
913
|
+
console.log(` 覆盖 ${f.path}`)
|
|
883
914
|
} else {
|
|
884
|
-
|
|
915
|
+
createTotal++
|
|
916
|
+
console.log(` 新建 ${f.path}`)
|
|
885
917
|
}
|
|
886
918
|
}
|
|
887
919
|
|
|
@@ -889,7 +921,7 @@ function main() {
|
|
|
889
921
|
const huskyDir = path.resolve(PROJECT_ROOT, ".husky")
|
|
890
922
|
const hasHusky = fs.existsSync(huskyDir)
|
|
891
923
|
if (!hasHusky) {
|
|
892
|
-
|
|
924
|
+
console.log(" 新建 .husky/ 目录")
|
|
893
925
|
}
|
|
894
926
|
|
|
895
927
|
const hooks = [
|
|
@@ -899,23 +931,86 @@ function main() {
|
|
|
899
931
|
|
|
900
932
|
for (const h of hooks) {
|
|
901
933
|
if (fileExists(h.path)) {
|
|
902
|
-
|
|
934
|
+
overwriteTotal++
|
|
935
|
+
console.log(` 覆盖 ${h.path}`)
|
|
903
936
|
} else {
|
|
904
|
-
|
|
937
|
+
createTotal++
|
|
938
|
+
console.log(` 新建 ${h.path}`)
|
|
905
939
|
}
|
|
906
940
|
}
|
|
907
941
|
|
|
908
|
-
|
|
942
|
+
console.log(
|
|
943
|
+
` 小计:覆盖 ${overwriteTotal} 个 · 新建 ${createTotal} 个` +
|
|
944
|
+
(backup ? " · 旧文件将备份到 .my-code-style-backup/" : "") +
|
|
945
|
+
(dryRun ? "(Dry run 预览,不写入)" : ""),
|
|
946
|
+
)
|
|
947
|
+
if (skipStylelint) {
|
|
948
|
+
console.log(" · 跳过 .stylelintrc.cjs(未检测到 CSS 预处理器)")
|
|
949
|
+
}
|
|
950
|
+
if (staleVersionrc) {
|
|
951
|
+
warn(
|
|
952
|
+
"检测到 ESM 项目 (type: module) 存在旧的 .versionrc.js,standard-version 需使用 .versionrc.cjs",
|
|
953
|
+
)
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
const printPackageJsonStep = () => {
|
|
957
|
+
stepHeader(4, 6, "package.json")
|
|
958
|
+
if (dryRun) {
|
|
959
|
+
console.log(
|
|
960
|
+
" · 将更新 scripts(lint / lint:fix / format / prepare / release / cz)与 lint-staged",
|
|
961
|
+
)
|
|
962
|
+
return
|
|
963
|
+
}
|
|
964
|
+
console.log(" ✓ scripts 已更新(lint / lint:fix / format / prepare / release / cz)")
|
|
965
|
+
console.log(" ✓ lint-staged 已按检测到的 CSS 预处理器生成")
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
const printDepsStep = () => {
|
|
969
|
+
stepHeader(5, 6, "依赖体检")
|
|
970
|
+
const findings = checkPeerDeps({ useFlatConfig, cssPreprocessor, projectType })
|
|
971
|
+
if (findings === 0) {
|
|
972
|
+
console.log(" ✓ 已装依赖版本都在要求范围内,声明的依赖也都已安装")
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
const printFooter = () => {
|
|
977
|
+
stepHeader(6, 6, "接下来")
|
|
978
|
+
console.log(` 1. 启用 husky hooks:${runScriptCommand(pm, "prepare")}`)
|
|
979
|
+
console.log(` 2. 首次检查:${runScriptCommand(pm, "lint")}`)
|
|
980
|
+
console.log(" 3. 使用 czg 提交 commit:")
|
|
981
|
+
console.log(` ${runScriptCommand(pm, "cz")}`)
|
|
982
|
+
console.log(
|
|
983
|
+
" (先 git add 暂存改动;交互步骤、类型与 scope 规则见本包 README《用 pnpm cz 提交》)",
|
|
984
|
+
)
|
|
985
|
+
if (pm === "pnpm") {
|
|
986
|
+
console.log("")
|
|
987
|
+
console.log(
|
|
988
|
+
" 提示:pnpm 10+ 默认拦截依赖的构建脚本,若安装时提示 ERR_PNPM_IGNORED_BUILDS(如 unrs-resolver),执行 pnpm approve-builds 后重试。",
|
|
989
|
+
)
|
|
990
|
+
}
|
|
909
991
|
console.log("")
|
|
910
|
-
|
|
992
|
+
if (dryRun) {
|
|
993
|
+
success("Dry run 结束:未写入任何文件;去掉 --dry-run 执行真实初始化")
|
|
994
|
+
} else {
|
|
995
|
+
success(
|
|
996
|
+
`初始化完成:覆盖 ${overwriteTotal} 个 · 新建 ${createTotal} 个 · package.json 已更新`,
|
|
997
|
+
)
|
|
998
|
+
}
|
|
911
999
|
console.log("")
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
// Dry run:把 package.json / 依赖体检 / 下一步三步也预览出来,然后结束
|
|
1003
|
+
if (dryRun) {
|
|
1004
|
+
printPackageJsonStep()
|
|
1005
|
+
printDepsStep()
|
|
1006
|
+
printFooter()
|
|
912
1007
|
return
|
|
913
1008
|
}
|
|
914
1009
|
|
|
915
1010
|
// Optional backup of existing files before modifying
|
|
916
|
-
const
|
|
1011
|
+
const backupDir = path.resolve(PROJECT_ROOT, ".my-code-style-backup")
|
|
1012
|
+
let backedUpCount = 0
|
|
917
1013
|
if (backup) {
|
|
918
|
-
const backupDir = path.resolve(PROJECT_ROOT, ".my-code-style-backup")
|
|
919
1014
|
ensureDir(backupDir)
|
|
920
1015
|
// package.json is rewritten (scripts + lint-staged), so it must be backed
|
|
921
1016
|
// up as well — users lose custom lint-staged groups otherwise.
|
|
@@ -925,7 +1020,7 @@ function main() {
|
|
|
925
1020
|
const targetPath = path.resolve(backupDir, item.path)
|
|
926
1021
|
ensureDir(path.dirname(targetPath))
|
|
927
1022
|
fs.copyFileSync(srcPath, targetPath)
|
|
928
|
-
|
|
1023
|
+
backedUpCount++
|
|
929
1024
|
}
|
|
930
1025
|
}
|
|
931
1026
|
}
|
|
@@ -1008,11 +1103,14 @@ function main() {
|
|
|
1008
1103
|
},
|
|
1009
1104
|
"lint-staged": getLintStagedConfig(cssPreprocessor),
|
|
1010
1105
|
})
|
|
1011
|
-
|
|
1106
|
+
printPackageJsonStep()
|
|
1012
1107
|
|
|
1013
1108
|
// The backup directory is ours, not the user's source — keep it out of git
|
|
1014
1109
|
if (backup) {
|
|
1015
1110
|
ensureGitignoreEntry(".my-code-style-backup/")
|
|
1111
|
+
console.log(
|
|
1112
|
+
` ✓ ${backedUpCount} 个旧文件已备份到 .my-code-style-backup/(目录已写入 .gitignore)`,
|
|
1113
|
+
)
|
|
1016
1114
|
}
|
|
1017
1115
|
} catch (err) {
|
|
1018
1116
|
console.error(`\n ✖ 初始化写入失败: ${err.message};正在回滚...`)
|
|
@@ -1048,40 +1146,8 @@ function main() {
|
|
|
1048
1146
|
return
|
|
1049
1147
|
}
|
|
1050
1148
|
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
console.log("")
|
|
1055
|
-
success("配置初始化完成!")
|
|
1056
|
-
console.log("")
|
|
1057
|
-
console.log(" 下一步:")
|
|
1058
|
-
console.log(" 1. 确保已安装 peerDependencies:")
|
|
1059
|
-
console.log(` ${addDevCommand(pm)} my-code-style`)
|
|
1060
|
-
if (useFlatConfig) {
|
|
1061
|
-
console.log(" 2. Flat Config 需要的额外依赖:")
|
|
1062
|
-
console.log(
|
|
1063
|
-
` ${addDevCommand(pm)} typescript-eslint globals eslint-plugin-import-x @eslint/js`,
|
|
1064
|
-
)
|
|
1065
|
-
console.log(" 3. 初始化 husky:")
|
|
1066
|
-
console.log(` ${runScriptCommand(pm, "prepare")}`)
|
|
1067
|
-
console.log(" 4. 使用 czg 提交 commit:")
|
|
1068
|
-
} else {
|
|
1069
|
-
console.log(" 2. 初始化 husky:")
|
|
1070
|
-
console.log(` ${runScriptCommand(pm, "prepare")}`)
|
|
1071
|
-
console.log(" 3. 使用 czg 提交 commit:")
|
|
1072
|
-
}
|
|
1073
|
-
console.log(` ${runScriptCommand(pm, "cz")}`)
|
|
1074
|
-
console.log(
|
|
1075
|
-
" (先 git add 暂存改动;交互步骤、类型与 scope 规则见本包 README《用 pnpm cz 提交》)",
|
|
1076
|
-
)
|
|
1077
|
-
if (pm === "pnpm") {
|
|
1078
|
-
console.log("")
|
|
1079
|
-
console.log(" 提示:pnpm 10+ 默认拦截依赖的构建脚本,若安装时提示")
|
|
1080
|
-
console.log(
|
|
1081
|
-
" ERR_PNPM_IGNORED_BUILDS(如 unrs-resolver),执行 pnpm approve-builds 后重试。",
|
|
1082
|
-
)
|
|
1083
|
-
}
|
|
1084
|
-
console.log("")
|
|
1149
|
+
printDepsStep()
|
|
1150
|
+
printFooter()
|
|
1085
1151
|
}
|
|
1086
1152
|
|
|
1087
1153
|
function modifyPackageJson(updates) {
|
|
@@ -1131,11 +1197,11 @@ function checkPeerDeps({
|
|
|
1131
1197
|
projectType = "base",
|
|
1132
1198
|
} = {}) {
|
|
1133
1199
|
const pkg = getProjectPkg()
|
|
1134
|
-
if (!pkg) return
|
|
1200
|
+
if (!pkg) return 0
|
|
1135
1201
|
|
|
1136
1202
|
// If running within the package itself, skip external missing deps check
|
|
1137
1203
|
if (pkg.name === "my-code-style") {
|
|
1138
|
-
return
|
|
1204
|
+
return 0
|
|
1139
1205
|
}
|
|
1140
1206
|
|
|
1141
1207
|
const baseDeps = [
|
|
@@ -1225,23 +1291,24 @@ function checkPeerDeps({
|
|
|
1225
1291
|
...(pkg.devDependencies || {}),
|
|
1226
1292
|
}
|
|
1227
1293
|
|
|
1228
|
-
checkInstalledVersions({ peerDeps, allPeerDeps })
|
|
1294
|
+
const versionProblems = checkInstalledVersions({ peerDeps, allPeerDeps })
|
|
1229
1295
|
|
|
1230
1296
|
const missing = allPeerDeps.filter((dep) => !allDeps[dep])
|
|
1231
1297
|
if (missing.length > 0) {
|
|
1232
1298
|
console.log("")
|
|
1233
|
-
warn(
|
|
1299
|
+
warn(`以下依赖未安装(${missing.length} 个):${missing.join(", ")}`)
|
|
1234
1300
|
console.log("")
|
|
1235
|
-
warn("
|
|
1236
|
-
console.log(`
|
|
1301
|
+
warn("一键安装命令(可整段粘贴执行):")
|
|
1302
|
+
console.log(` ${addDevCommand(detectPackageManager())} my-code-style \\`)
|
|
1237
1303
|
missing.forEach((dep, i) => {
|
|
1238
1304
|
const version =
|
|
1239
1305
|
dep === "eslint" ? (useFlatConfig ? "^9.0.0" : "^8.57.0") : peerDeps[dep] || ""
|
|
1240
|
-
const depWithVersion = version ? `${dep}@${version}` : dep
|
|
1306
|
+
const depWithVersion = shellSafeSpec(version ? `${dep}@${version}` : dep)
|
|
1241
1307
|
const suffix = i < missing.length - 1 ? " \\" : ""
|
|
1242
|
-
console.log(`
|
|
1308
|
+
console.log(` ${depWithVersion}${suffix}`)
|
|
1243
1309
|
})
|
|
1244
1310
|
}
|
|
1311
|
+
return missing.length + versionProblems
|
|
1245
1312
|
}
|
|
1246
1313
|
|
|
1247
1314
|
// 体检时会顺着这些包的 peerDependencies 反查底层依赖的实际版本
|
|
@@ -1337,14 +1404,17 @@ function checkInstalledVersions({ peerDeps, allPeerDeps, rootDir = PROJECT_ROOT
|
|
|
1337
1404
|
}
|
|
1338
1405
|
}
|
|
1339
1406
|
|
|
1340
|
-
if (!problems.length) return
|
|
1407
|
+
if (!problems.length) return 0
|
|
1341
1408
|
console.log("");
|
|
1342
|
-
warn(
|
|
1343
|
-
for (const problem of problems) console.log(`
|
|
1409
|
+
warn(`以下依赖已安装,但版本与当前配置不匹配(${problems.length} 个):`);
|
|
1410
|
+
for (const problem of problems) console.log(` · ${problem.message}`);
|
|
1344
1411
|
console.log("");
|
|
1345
|
-
warn("
|
|
1412
|
+
warn("对齐命令(可整段粘贴执行;也可以把上游配置包降到匹配的大版本):");
|
|
1346
1413
|
const targets = [...new Set(problems.map((problem) => problem.target))];
|
|
1347
|
-
console.log(
|
|
1414
|
+
console.log(
|
|
1415
|
+
` ${addDevCommand(detectPackageManager())} ${targets.map(shellSafeSpec).join(" ")}`,
|
|
1416
|
+
);
|
|
1417
|
+
return problems.length
|
|
1348
1418
|
}
|
|
1349
1419
|
|
|
1350
1420
|
// Only run when executed directly; requiring this file must be side-effect free.
|
package/package.json
CHANGED