my-code-style 1.6.1 → 1.7.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 +13 -0
- package/README.md +33 -22
- package/bin/init +149 -16
- package/package.json +11 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
## 变更日志
|
|
2
2
|
|
|
3
|
+
## [1.7.0](https://github.com/myvn/codeStyle/compare/v1.6.1...v1.7.0) (2026-09-20)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### 🐛 Bug Fixes | Bug 修复
|
|
7
|
+
|
|
8
|
+
* **deps:** stylelint 生态 peer 放宽到 16/17 两条线,并补 Stylelint 17 运行时回归 ([a230edc](https://github.com/myvn/codeStyle/commit/a230edcae73d2b935977567b8f082aaaa74dc938))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### ✨ Features | 新功能
|
|
12
|
+
|
|
13
|
+
* **init:** 依赖版本体检 —— 已装但版本不匹配、上游配置 peer 冲突、parser 错位 ([2820834](https://github.com/myvn/codeStyle/commit/2820834bc3062900724132f7b29c2581eace13e8))
|
|
14
|
+
* **init:** 版本体检精确到 minor —— 只比主版本会漏掉 10.2.0 vs ^10.3.0 ([d13629c](https://github.com/myvn/codeStyle/commit/d13629c947575109ed3319854ab902e5caada145))
|
|
15
|
+
|
|
3
16
|
### [1.6.1](https://github.com/myvn/codeStyle/compare/v1.6.0...v1.6.1) (2026-09-18)
|
|
4
17
|
|
|
5
18
|
## [1.6.0](https://github.com/myvn/codeStyle/compare/v1.4.0...v1.6.0) (2026-09-18)
|
package/README.md
CHANGED
|
@@ -185,13 +185,15 @@ npx my-code-style-init [--dry-run] [--backup] [--version|-v] [--help|-h]
|
|
|
185
185
|
| 提交信息被拒(`type may not be empty` / `subject may not be empty`) | 提交信息需符合 conventional commits | 用 `pnpm cz` 交互式生成;header 上限 108 字符 |
|
|
186
186
|
| 老项目已有 `.eslintrc.*`,init 只读退出 | ESLint 版本与配置格式冲突时 CLI 拒绝写入 | 先确认/迁移版本,再重跑 init |
|
|
187
187
|
| `pnpm release` 之后如何发布 | `release` 只生成版本、CHANGELOG、提交与 tag | 另行执行 `npm publish` |
|
|
188
|
+
| 装完看到一片 `unmet peer` 警告,要不要管 | npm 遇到不满足的 peer 会直接 ERESOLVE 拒装,pnpm 只打印 WARN 就装完 | 先看警告来自谁:`unmet peer … from my-code-style` 说明版本声明没跟上,先升级本包;来自别的包(如 `postcss-html@1.8.1` 却要 `^2`)按提示对齐。重跑 `init` 会主动体检(范围精确到 minor,例如 `vue-eslint-parser 10.2.0` 不满足 `^10.3.0`)并打印对齐命令 |
|
|
189
|
+
| `stylelint` 该用 16 还是 17 | 两条线都支持:`stylelint ^16.24.0 \|\| ^17.0.0` | 16 线(`stylelint-config-recommended@17`)兼容面最广;17 线要 stylelint 17 + `config-recommended@18` + `recommended-scss@17` + `stylelint-order@7/8`,且 Node ≥ 22.12。两条线都有真实运行回归(集成套件跑 16 线,Stylelint 17 套件跑 17 线) |
|
|
188
190
|
|
|
189
191
|
完整 FAQ(含更多场景与解释)见 [docs/manual.md](docs/manual.md#五使用中遇到的问题faq)。
|
|
190
192
|
|
|
191
193
|
## 测试套件
|
|
192
194
|
|
|
193
195
|
```bash
|
|
194
|
-
npm run test:all # 全量运行
|
|
196
|
+
npm run test:all # 全量运行 168 项:用例明细 + 分类统计 + 最慢文件定位
|
|
195
197
|
npm run diagnose # 换机器后先跑它:进程 / git / 文件系统 / hooks 各占多少
|
|
196
198
|
npm run sweep # 给本机找最佳文件级并发(扫 integration 套件)
|
|
197
199
|
npm test # 只跑基础 CLI 与配置矩阵(70 项)
|
|
@@ -199,6 +201,8 @@ npm run test:integration:setup # 安装现代化隔离依赖运行环境
|
|
|
199
201
|
npm run test:integration # Flat Config、真实 Husky 及提交链路测试(55 项)
|
|
200
202
|
npm run test:legacy:setup # 安装 ESLint 8 隔离运行环境
|
|
201
203
|
npm run test:legacy # ESLint 8.57.0 兼容性回归测试(27 项)
|
|
204
|
+
npm run test:stylelint17:setup # 安装 Stylelint 17 隔离运行环境
|
|
205
|
+
npm run test:stylelint17 # Stylelint 17 生态兼容性回归(8 项)
|
|
202
206
|
```
|
|
203
207
|
|
|
204
208
|
`npm run test:all` 由 `scripts/test-all.cjs` 驱动,输出**套件 → 用例 → 汇总**三层:
|
|
@@ -207,38 +211,44 @@ npm run test:legacy # ESLint 8.57.0 兼容性回归测试(27 项)
|
|
|
207
211
|
```text
|
|
208
212
|
my-code-style 测试套件
|
|
209
213
|
|
|
210
|
-
▶ [1/
|
|
214
|
+
▶ [1/4] 基础 CLI 与配置矩阵 (共 78 项,5 文件 · 3 文件并发(自动:2 核 / 内存 4G))
|
|
211
215
|
✓ 运行器 TAP 解析:统计通过与失败、SKIP 与每用例耗时 · 2ms
|
|
212
|
-
✓
|
|
213
|
-
✓
|
|
216
|
+
✓ 依赖版本体检:两位数主版本(stylelint 17)不再被静默跳过 · 41ms
|
|
217
|
+
✓ 所有公共导出目标存在且可通过包名解析 · 3ms
|
|
214
218
|
…
|
|
215
|
-
✓ 通过
|
|
219
|
+
✓ 通过 78 · 3.2s · 最慢文件 init-matrix.test.cjs 3.0s
|
|
216
220
|
|
|
217
|
-
▶ [2/
|
|
218
|
-
✓ 完整提交链:JS/TS/Vue/nvue/CSS/scss 自动修复及二次复检 ·
|
|
219
|
-
✓ 完整提交链拦截 nvue 内嵌样式错误(不是仅检查脚本) · 3.6s
|
|
221
|
+
▶ [2/4] 现代工具链与提交链 (共 55 项,23 文件 · 3 文件并发(自动:2 核 / 内存 4G))
|
|
222
|
+
✓ 完整提交链:JS/TS/Vue/nvue/CSS/scss 自动修复及二次复检 · 10.7s
|
|
220
223
|
✓ Flat Config 启用 eslint:recommended 核心规则:no-debugger · 45ms
|
|
221
224
|
…
|
|
222
|
-
✓ 通过 55 ·
|
|
225
|
+
✓ 通过 55 · 42.7s · 最慢文件 commit-chain-scss.test.cjs 11.4s
|
|
223
226
|
|
|
224
|
-
▶ [3/
|
|
225
|
-
✓ ESLint 8 base:生成的 lint 脚本遍历并拦截 broken.ts · 1.
|
|
227
|
+
▶ [3/4] ESLint 8 兼容性 (共 27 项,1 文件 · 3 文件并发(自动:2 核 / 内存 4G))
|
|
228
|
+
✓ ESLint 8 base:生成的 lint 脚本遍历并拦截 broken.ts · 1.3s
|
|
226
229
|
…
|
|
227
|
-
✓ 通过 27 ·
|
|
230
|
+
✓ 通过 27 · 19.0s
|
|
231
|
+
|
|
232
|
+
▶ [4/4] Stylelint 17 兼容性 (共 8 项,1 文件 · 3 文件并发(自动:2 核 / 内存 4G))
|
|
233
|
+
✓ stylelint 17 下 --fix 生效且幂等(SCSS) · 1.4s
|
|
234
|
+
✓ stylelint-order(recess-order 7 的 peer)在 stylelint 17 下可用 · 1.0s
|
|
235
|
+
…
|
|
236
|
+
✓ 通过 8 · 7.4s
|
|
228
237
|
|
|
229
238
|
──────────────────────────────────────────────────────
|
|
230
239
|
套件 通过 失败 跳过 用时
|
|
231
240
|
──────────────────────────────────────────────────────
|
|
232
|
-
基础 CLI 与配置矩阵
|
|
233
|
-
现代工具链与提交链 55 0 -
|
|
234
|
-
ESLint 8 兼容性 27 0 -
|
|
241
|
+
基础 CLI 与配置矩阵 78 0 - 3.2s
|
|
242
|
+
现代工具链与提交链 55 0 - 42.7s
|
|
243
|
+
ESLint 8 兼容性 27 0 - 19.0s
|
|
244
|
+
Stylelint 17 兼容性 8 0 - 7.4s
|
|
235
245
|
──────────────────────────────────────────────────────
|
|
236
|
-
合计
|
|
246
|
+
合计 168 0 - 72.3s
|
|
237
247
|
──────────────────────────────────────────────────────
|
|
238
248
|
|
|
239
|
-
⏱ 最慢文件:eslint8.test.cjs
|
|
249
|
+
⏱ 最慢文件:eslint8.test.cjs 19.0s · commit-chain-scss.test.cjs 11.4s · commit-chain-less.test.cjs 11.1s
|
|
240
250
|
|
|
241
|
-
✅ 全部通过:
|
|
251
|
+
✅ 全部通过:168/168 项,用时 72.3s
|
|
242
252
|
```
|
|
243
253
|
|
|
244
254
|
|
|
@@ -248,7 +258,7 @@ npm run test:legacy # ESLint 8.57.0 兼容性回归测试(27 项)
|
|
|
248
258
|
| 参数 | 作用 |
|
|
249
259
|
| -------------------- | ------------------------------------------------------------- |
|
|
250
260
|
| `-- --quiet` | 只看套件结论与汇总表,不列用例明细(长输出时用) |
|
|
251
|
-
| `-- --parallel` |
|
|
261
|
+
| `-- --parallel` | 强制四个套件同时跑(核数 ≥ 8 时默认已自动开启) |
|
|
252
262
|
| `-- --serial` | 强制串行(CI 形态,输出顺序最稳定) |
|
|
253
263
|
| `-- --jobs=2` | 配合并行限制同时运行的套件数,其余排队(面板显示"等待中") |
|
|
254
264
|
| `-- --suite=base,legacy` | 只跑指定套件(base / integration / legacy,逗号分隔) |
|
|
@@ -280,7 +290,8 @@ npm run test:all -- --profile # 看每个测试文件耗时,定位瓶颈
|
|
|
280
290
|
- **文件级**:集成套件按"一条提交链一个文件"拆成 23 个测试文件,**由运行器自己按文件
|
|
281
291
|
调度**(每个文件一个 `node --test` 进程),不依赖 Node 的 `--test` 默认并发值——
|
|
282
292
|
同一个文件内的用例仍然串行(真实 git 仓库不能并行改),文件之间才是并发的。
|
|
283
|
-
-
|
|
293
|
+
- **套件级**:四个套件再并行,互不共享目录(基础只碰系统临时目录,集成用
|
|
294
|
+
`demo-test/.runtime`,ESLint 8 用 `.runtime-legacy`,Stylelint 17 用 `.runtime-sl17`)。
|
|
284
295
|
|
|
285
296
|
因为每个文件里跑的都是真实 `git commit`(单次 0.5–3.9s),墙钟由**最慢的那个文件**
|
|
286
297
|
决定,所以文件尽量拆到"一个文件一次提交"。每个套件跑完会直接告诉你最慢文件是谁,
|
|
@@ -306,13 +317,13 @@ npm run test:all -- --profile # 看每个测试文件耗时,定位瓶颈
|
|
|
306
317
|
并发 git/npx 撑到 OOM(进程被 SIGKILL);文件数多于并发数时,**用例少的文件(多半是同
|
|
307
318
|
一条重链)优先开跑**,避免长任务被排进最后一波、墙钟再多乘一倍。
|
|
308
319
|
|
|
309
|
-
实测(2 核沙箱,
|
|
320
|
+
实测(2 核沙箱,168 项;沙箱内存 4G,所以自动并发是 3):
|
|
310
321
|
|
|
311
322
|
| 运行方式 | 墙钟时间 |
|
|
312
323
|
| ----------------------------------- | ----------------------------------------------- |
|
|
313
324
|
| 串行套件 + 文件级并发 1(CI 旧形态) | 62.4s(hook 改造前同配置 70.3s) |
|
|
314
325
|
| 串行套件 + 自动并发 3(默认) | 47.2s(hook 改造前同配置 51.8s) |
|
|
315
|
-
| `--parallel`
|
|
326
|
+
| `--parallel` 四套件 + 自动并发 3 | 43.0s(hook 改造前同配置 46.6s) |
|
|
316
327
|
| `node --test demo-test/integration/*.test.cjs`(Node 自己调度,等同旧命令) | 43.7s(只看集成套件那一段) |
|
|
317
328
|
| `npm run test:integration`(运行器调度,自动并发 3) | 30.6s(只看集成套件那一段) |
|
|
318
329
|
| 串行套件 + 文件级并发 23(全部一波) | ✗ 3.8G 内存沙箱被 OOM 压垮(19 项 SIGKILL) |
|
package/bin/init
CHANGED
|
@@ -211,6 +211,25 @@ function rangeIntervals(range) {
|
|
|
211
211
|
return intervals
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
+
/**
|
|
215
|
+
* 判断某个具体版本(含 minor / patch)是否落在声明的范围内。
|
|
216
|
+
*
|
|
217
|
+
* 为什么不用主版本判断:`vue-eslint-parser ^10.3.0` 与装到的 10.2.0 主版本相同,
|
|
218
|
+
* 但 10.3 才是 Vue 插件 10 的兼容下限,只比主版本会漏掉这类 minor 级错位。
|
|
219
|
+
* 这里直接做区间相交判断,既不受主版本位数限制(stylelint 16/17),也不丢 minor。
|
|
220
|
+
* 返回 null 表示范围无法解析(不判断)。
|
|
221
|
+
*/
|
|
222
|
+
function satisfiesRange(range, version) {
|
|
223
|
+
const parts = parseVersionFields(version)
|
|
224
|
+
if (!parts || parts.some((part) => part === null)) return null
|
|
225
|
+
const target = lowerBound(parts)
|
|
226
|
+
const intervals = rangeIntervals(range)
|
|
227
|
+
if (!intervals.length) return null
|
|
228
|
+
return intervals.some(
|
|
229
|
+
([lower, upper]) => compareVersion(lower, target) <= 0 && compareVersion(target, upper) < 0,
|
|
230
|
+
)
|
|
231
|
+
}
|
|
232
|
+
|
|
214
233
|
/**
|
|
215
234
|
* List every major version a declared range can install (0-12), or null when
|
|
216
235
|
* the range cannot be parsed.
|
|
@@ -233,18 +252,13 @@ function majorsForRange(range) {
|
|
|
233
252
|
}
|
|
234
253
|
|
|
235
254
|
/**
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
*
|
|
239
|
-
* like a workspace root (package.json / pnpm-workspace.yaml / lerna.json).
|
|
255
|
+
* 读取任意包在本项目(或向上寻找的“工作区根”)里实际安装的版本。
|
|
256
|
+
* monorepo 里依赖常被提升到工作区根,所以要向上走;只采纳项目根或带
|
|
257
|
+
* manifest 的祖先目录,避免把无关上级目录的 node_modules 当成本项目依赖。
|
|
240
258
|
*/
|
|
241
|
-
function
|
|
259
|
+
function findInstalledPackage(pkgName, rootDir) {
|
|
242
260
|
let dir = rootDir
|
|
243
261
|
for (let depth = 0; depth < 8; depth += 1) {
|
|
244
|
-
// 只采纳项目根或“像工作区根”的祖先里的安装(package.json / pnpm-workspace.yaml /
|
|
245
|
-
// lerna.json)。中间层(如 monorepo 的 packages/)通常没有任何 manifest,
|
|
246
|
-
// 必须继续向上找;而完全无关的上级目录(例如 /tmp 或 $HOME 的 node_modules)
|
|
247
|
-
// 即使存在 eslint 也不能当作项目依赖。
|
|
248
262
|
const isProjectRoot = dir === rootDir
|
|
249
263
|
const isWorkspaceRoot =
|
|
250
264
|
fs.existsSync(path.resolve(dir, "package.json")) ||
|
|
@@ -253,16 +267,20 @@ function findInstalledEslintMajor(rootDir) {
|
|
|
253
267
|
|
|
254
268
|
if (isProjectRoot || isWorkspaceRoot) {
|
|
255
269
|
try {
|
|
256
|
-
const
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
270
|
+
const manifestPath = path.resolve(
|
|
271
|
+
dir,
|
|
272
|
+
"node_modules",
|
|
273
|
+
...pkgName.split("/"),
|
|
274
|
+
"package.json",
|
|
275
|
+
)
|
|
276
|
+
if (fs.existsSync(manifestPath)) {
|
|
277
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"))
|
|
278
|
+
if (manifest.version) {
|
|
279
|
+
return { version: String(manifest.version), dir, manifest }
|
|
262
280
|
}
|
|
263
281
|
}
|
|
264
282
|
} catch {
|
|
265
|
-
//
|
|
283
|
+
// 忽略读不动的安装(半装状态),继续向上找
|
|
266
284
|
}
|
|
267
285
|
}
|
|
268
286
|
|
|
@@ -273,6 +291,16 @@ function findInstalledEslintMajor(rootDir) {
|
|
|
273
291
|
return null
|
|
274
292
|
}
|
|
275
293
|
|
|
294
|
+
/**
|
|
295
|
+
* 读取实际安装的 ESLint 主版本号(见 findInstalledPackage 的查找规则)。
|
|
296
|
+
*/
|
|
297
|
+
function findInstalledEslintMajor(rootDir) {
|
|
298
|
+
const installed = findInstalledPackage("eslint", rootDir)
|
|
299
|
+
if (!installed) return null
|
|
300
|
+
const major = parseInt(String(installed.version).split(".")[0], 10)
|
|
301
|
+
return Number.isNaN(major) ? null : major
|
|
302
|
+
}
|
|
303
|
+
|
|
276
304
|
/**
|
|
277
305
|
* Detect ESLint major version from the installed package or the declared range.
|
|
278
306
|
* Returns 8, 9, 10, … or null (not installed and no usable range).
|
|
@@ -1194,6 +1222,8 @@ function checkPeerDeps({
|
|
|
1194
1222
|
...(pkg.devDependencies || {}),
|
|
1195
1223
|
}
|
|
1196
1224
|
|
|
1225
|
+
checkInstalledVersions({ peerDeps, allPeerDeps })
|
|
1226
|
+
|
|
1197
1227
|
const missing = allPeerDeps.filter((dep) => !allDeps[dep])
|
|
1198
1228
|
if (missing.length > 0) {
|
|
1199
1229
|
console.log("")
|
|
@@ -1211,6 +1241,109 @@ function checkPeerDeps({
|
|
|
1211
1241
|
}
|
|
1212
1242
|
}
|
|
1213
1243
|
|
|
1244
|
+
// 体检时会顺着这些包的 peerDependencies 反查底层依赖的实际版本
|
|
1245
|
+
const PEER_SOURCE_PACKAGES = [
|
|
1246
|
+
"stylelint-config-recommended",
|
|
1247
|
+
"stylelint-config-recommended-scss",
|
|
1248
|
+
"stylelint-config-recommended-vue",
|
|
1249
|
+
"stylelint-config-html",
|
|
1250
|
+
"stylelint-config-recess-order",
|
|
1251
|
+
"stylelint-prettier",
|
|
1252
|
+
]
|
|
1253
|
+
// 只反查这些“装错就真的会坏”的底层包,避免把上游配置之间的宽松约束也报出来
|
|
1254
|
+
const PEER_SOURCE_TARGETS = [
|
|
1255
|
+
"stylelint",
|
|
1256
|
+
"stylelint-order",
|
|
1257
|
+
"postcss-html",
|
|
1258
|
+
"stylelint-config-recommended",
|
|
1259
|
+
"stylelint-config-html",
|
|
1260
|
+
"stylelint-config-recommended-scss",
|
|
1261
|
+
]
|
|
1262
|
+
|
|
1263
|
+
/**
|
|
1264
|
+
* 已装依赖的版本体检。
|
|
1265
|
+
*
|
|
1266
|
+
* 为什么需要它:npm 遇到不满足的 peer 会直接 ERESOLVE 拒装,pnpm 只打印一行
|
|
1267
|
+
* WARN 就装完,于是“装是装上了,跑起来才坏”的组合会长期潜伏。这里把两类问题
|
|
1268
|
+
* 主动查出来并给出对齐命令(只做 major 级别判断,保持零依赖):
|
|
1269
|
+
* 1. 我们声明的 peer 范围 vs 项目里实际安装的版本(含 minor / patch);
|
|
1270
|
+
* 2. 上游配置包自己的 peer(例如 stylelint-config-recommended@18 要求
|
|
1271
|
+
* stylelint ^17),以及 typescript-eslint 与其 parser/plugin 的版本错位。
|
|
1272
|
+
*/
|
|
1273
|
+
function checkInstalledVersions({ peerDeps, allPeerDeps, rootDir = PROJECT_ROOT }) {
|
|
1274
|
+
const problems = [];
|
|
1275
|
+
const seen = new Set();
|
|
1276
|
+
const add = (name, message, target) => {
|
|
1277
|
+
const key = `${name}\u0000${message}`;
|
|
1278
|
+
if (seen.has(key)) return;
|
|
1279
|
+
seen.add(key);
|
|
1280
|
+
problems.push({ name, message, target });
|
|
1281
|
+
};
|
|
1282
|
+
const minorOf = (version) => String(version).split(".").slice(0, 2).join(".");
|
|
1283
|
+
|
|
1284
|
+
// 1) 本工具的 peer 范围 vs 实际安装
|
|
1285
|
+
for (const dep of allPeerDeps) {
|
|
1286
|
+
const range = dep === "eslint" ? peerDeps.eslint : peerDeps[dep];
|
|
1287
|
+
if (!range || range === "*" || range.startsWith("npm:")) continue;
|
|
1288
|
+
const installed = findInstalledPackage(dep, rootDir);
|
|
1289
|
+
if (!installed) continue;
|
|
1290
|
+
const allowed = satisfiesRange(range, installed.version);
|
|
1291
|
+
if (allowed === null || allowed) continue;
|
|
1292
|
+
add(dep, `${dep} 装了 ${installed.version},本工具要求 ${range}`, `${dep}@${range}`);
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
// 2) 上游配置包的 peer vs 实际安装(配置文件本身也会挑底层版本)
|
|
1296
|
+
for (const dep of PEER_SOURCE_PACKAGES) {
|
|
1297
|
+
const source = findInstalledPackage(dep, rootDir);
|
|
1298
|
+
if (!source) continue;
|
|
1299
|
+
for (const [target, range] of Object.entries(source.manifest.peerDependencies || {})) {
|
|
1300
|
+
if (!PEER_SOURCE_TARGETS.includes(target)) continue;
|
|
1301
|
+
if (range === "*" || String(range).startsWith("npm:")) continue;
|
|
1302
|
+
const installed = findInstalledPackage(target, rootDir);
|
|
1303
|
+
if (!installed) {
|
|
1304
|
+
if (!rangeIntervals(range).length) continue;
|
|
1305
|
+
add(
|
|
1306
|
+
target,
|
|
1307
|
+
`${dep}@${source.version} 需要 ${target}@${range},项目里没有安装`,
|
|
1308
|
+
`${target}@${range}`,
|
|
1309
|
+
);
|
|
1310
|
+
continue;
|
|
1311
|
+
}
|
|
1312
|
+
const allowed = satisfiesRange(range, installed.version);
|
|
1313
|
+
if (allowed === null || allowed) continue;
|
|
1314
|
+
add(
|
|
1315
|
+
target,
|
|
1316
|
+
`${dep}@${source.version} 要求 ${target}@${range},实际装了 ${installed.version}`,
|
|
1317
|
+
`${target}@${range}`,
|
|
1318
|
+
);
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
// 3) typescript-eslint 与 @typescript-eslint/parser、eslint-plugin 必须同版本
|
|
1323
|
+
const meta = findInstalledPackage("typescript-eslint", rootDir);
|
|
1324
|
+
if (meta) {
|
|
1325
|
+
for (const sibling of ["@typescript-eslint/parser", "@typescript-eslint/eslint-plugin"]) {
|
|
1326
|
+
const installed = findInstalledPackage(sibling, rootDir);
|
|
1327
|
+
if (!installed) continue;
|
|
1328
|
+
if (minorOf(installed.version) === minorOf(meta.version)) continue;
|
|
1329
|
+
add(
|
|
1330
|
+
sibling,
|
|
1331
|
+
`${sibling}@${installed.version} 与 typescript-eslint@${meta.version} 不是同一版本`,
|
|
1332
|
+
`${sibling}@${meta.version}`,
|
|
1333
|
+
);
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
if (!problems.length) return;
|
|
1338
|
+
console.log("");
|
|
1339
|
+
warn("以下依赖已安装,但版本与当前配置不匹配:");
|
|
1340
|
+
for (const problem of problems) console.log(` · ${problem.message}`);
|
|
1341
|
+
console.log("");
|
|
1342
|
+
warn("对齐命令(也可以把上游配置包降到与你现有版本匹配的大版本):");
|
|
1343
|
+
const targets = [...new Set(problems.map((problem) => problem.target))];
|
|
1344
|
+
console.log(` ${addDevCommand(detectPackageManager())} ${targets.join(" ")}`);
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1214
1347
|
// Only run when executed directly; requiring this file must be side-effect free.
|
|
1215
1348
|
if (require.main === module) {
|
|
1216
1349
|
main()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "my-code-style",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
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",
|
|
@@ -47,7 +47,9 @@
|
|
|
47
47
|
"test:integration:setup": "node demo-test/setup-integration.cjs",
|
|
48
48
|
"test:integration": "node scripts/test-all.cjs --suite=integration",
|
|
49
49
|
"test:legacy:setup": "node demo-test/setup-legacy.cjs",
|
|
50
|
+
"test:stylelint17:setup": "node demo-test/setup-stylelint17.cjs",
|
|
50
51
|
"test:legacy": "node scripts/test-all.cjs --suite=legacy",
|
|
52
|
+
"test:stylelint17": "node scripts/test-all.cjs --suite=stylelint17",
|
|
51
53
|
"test:all": "node scripts/test-all.cjs",
|
|
52
54
|
"diagnose": "node scripts/diagnose-speed.cjs",
|
|
53
55
|
"sweep": "node scripts/sweep-concurrency.cjs",
|
|
@@ -88,12 +90,13 @@
|
|
|
88
90
|
"postcss-scss": "^4.0.0",
|
|
89
91
|
"prettier": "^3.0.0",
|
|
90
92
|
"standard-version": "^9.0.0",
|
|
91
|
-
"stylelint": "^16.0.0",
|
|
93
|
+
"stylelint": "^16.24.0 || ^17.0.0",
|
|
92
94
|
"stylelint-config-html": "^2.0.0",
|
|
93
|
-
"stylelint-config-recess-order": "^5.0.0",
|
|
94
|
-
"stylelint-config-recommended": "^17.0.0",
|
|
95
|
-
"stylelint-config-recommended-scss": "^16.0.0",
|
|
95
|
+
"stylelint-config-recess-order": "^5.0.0 || ^6.0.0 || ^7.0.0",
|
|
96
|
+
"stylelint-config-recommended": "^17.0.0 || ^18.0.0",
|
|
97
|
+
"stylelint-config-recommended-scss": "^16.0.0 || ^17.0.0",
|
|
96
98
|
"stylelint-config-recommended-vue": "^2.0.0",
|
|
99
|
+
"stylelint-order": "^6.0.0 || ^7.0.0 || ^8.0.0",
|
|
97
100
|
"stylelint-prettier": "^5.0.0",
|
|
98
101
|
"typescript": "^5.0.0",
|
|
99
102
|
"typescript-eslint": "^8.0.0",
|
|
@@ -181,6 +184,9 @@
|
|
|
181
184
|
"stylelint-config-recommended-vue": {
|
|
182
185
|
"optional": true
|
|
183
186
|
},
|
|
187
|
+
"stylelint-order": {
|
|
188
|
+
"optional": true
|
|
189
|
+
},
|
|
184
190
|
"stylelint-prettier": {
|
|
185
191
|
"optional": true
|
|
186
192
|
},
|