Skip to content

prettier 是未接线的 devDependency:无配置、无 lint 集成、无工作流,prettier --check 对全仓假红 #3657

Description

@yinlianghui

观察类发现,在 PR #3656(#3587 / #3648,纯注释改动)的验证环节撞到。今天没有任何用户或 CI 会碰到它;不在那两单的完成范围内,按围栏未顺手改。

事实

prettier@^3.9.6 在根 package.json 的 devDependencies 里,但它没有接到任何地方:

  • 无配置:仓根没有 .prettierrc / .prettierrc.* / prettier.config.*,package.json 里也没有 prettier 键;
  • 无忽略表:没有 .prettierignore;
  • 无 lint 集成:eslint.config.js 一次都没提 prettier(没有 eslint-config-prettier / eslint-plugin-prettier);
  • 无工作流:grep -rln prettier .github/workflows/ 零命中;
  • 无文档提及:grep -rn prettier --include='*.md' --include='*.mdx' 零命中(AGENTS.md / CONTRIBUTING.md 都没让人跑它);
  • 全仓(排除 node_modules)提到 prettier 的文件只有两个:package.json 与 pnpm-lock.yaml。

也没有 .editorconfig。

后果:一个会骗人的假红

因为没有配置,pnpm exec prettier --check 用的是 prettier 的默认值(双引号、printWidth: 80),而本仓代码是单引号、行宽更宽。结果是几乎每个文件都被报成 unformatted。在未经修改的 origin/main 内容上实测(把 git show origin/main:FILE 喂给 prettier --stdin-filepath FILE,再 diff):

文件 与 prettier 默认格式的差异行数
scripts/check-doc-links.mjs 389
scripts/__tests__/check-doc-links.test.ts 1646

差异内容就是 'node:fs' → "node:fs" 这一类,与任何人的改动无关。

危险的地方在于这是个看起来像自己闯的祸的假红:一个 agent 改完两行注释,顺手跑 prettier --check 做收尾验证,看到自己刚碰的两个文件报 warn,最自然的下一步是 prettier --write —— 那会把几千行无关代码重排成本仓并不使用的风格,混进一个注释级 PR 里。PR #3656 里我就在这上面停了一拍,靠回测 origin/main 的原始内容才确认不是自己引入的。

影响

零用户可见影响,零 CI 影响(没有工作流跑它)。归为 observation-class。它的成本是给后来的 agent 埋了一个"看起来是你干的"的假信号,以及一条永远装不上用场的依赖。

处置方向(分诊定,我不预设)

大致是 enforce-or-remove 的老三选:

  1. 接线:补一份与现有风格一致的 prettier 配置(单引号等)+ .prettierignore,并挂进 lint。代价是首次落地要么全仓重排一次,要么靠 ignore 表圈定范围;
  2. 移除:从 devDependencies 删掉这条没人用的依赖,格式一律交给 eslint;
  3. 只加护栏:保留依赖,但补一份配置或在 AGENTS.md 写明"本仓不用 prettier 做格式门禁,别跑它" —— 成本最低,但依赖仍然是死的。

倾向 2 或 1,视仓主是否真想要一个格式门禁而定;3 只是止血。


Generated by Claude Code

Activity

  1. self-assigned this
    on Aug 7, 2026
  2. yinlianghui commented on Aug 7, 2026

    @yinlianghui
    CollaboratorAuthor

    认领(PM 派发),处置裁决:enforce-or-remove → remove。测量已死(零配置、零 workflow、eslint 不引、文档零提及),且是活的「看起来像自己闯的祸」假红陷阱(--check 默认值对 main 原始内容假红 389/1646 行,下一个 agent 顺手 --write 即数千行无关重排)— 与 scripts/start-app.mjs 的删除同理。

    • Session: session_01GTRjn8xBqp75dk7kFupVRt
    • 分支:claude/issue-3657-remove-unwired-prettier
    • 文件面:根 package.json(删 prettier devDependency)+ pnpm-lock.yaml(随 install 再生)。先全量复测四类接线(配置文件/workflow/eslint 配置/所有 package.json scripts)确认零引用后再删;删后 pnpm install 再生 lockfile,pnpm exec prettier --version 应失败(逆向验证:删前成功、删后不可解析)。
    • PR 正文写明重新引入的正确路径(配置 + 接线 + 一次性全仓格式化基线 = enforce 路;本次走 remove 路的依据)。无 changeset(工具链 devDependency,零发布物影响,写明判断)。

    Generated by Claude Code

  3. yinlianghui commented on Aug 7, 2026

    @yinlianghui
    CollaboratorAuthor

    验收 ACCEPT → PR #3681(session_01GTRjn8xBqp75dk7kFupVRt)。

    已核:四类接线 + 超范围五面全零(且审计在 install 前跑,排除 node_modules 噪音 — 记入方法库);lockfile 差异 11 删 0 增,prettier@2.8.8 作为 changesets 传递依赖有意保留并验证 — 精确删除不误伤。

    裁决记录:

    1. 逆向验证反转的如实报告是本单最有价值的产出:全局 prettier 3.8.1 兜住了 pnpm exec 的 PATH 回退 — 「repo 不再声明」已达成(版本变化 + .bin 消失 + lockfile 零命中三重证明),「陷阱物理消失」未达成且变得更隐蔽。不硬凑预测方向、把后果写成新单,正确。
    2. 量级双报(389/1646 是 issue 自己的 diff|wc 方法、纯变更行 287/1198)— 不鹦鹉学舌任一数字,好。
    3. 删掉 prettier 依赖不足以消灭假红陷阱:pnpm exec 会沿 PATH 落到全局 prettier 上 #3682 定级入队即派(AGENTS.md 护栏 = 修复的承重另一半)。
    4. issue 勘误(ValidationPreview.tsx 的英语形容词 prettier)收录。

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions