每个写过前端的人,大概都经历过这种诡异场景:明明在 Cursor 里装好了 Prettier,settings.json里也写了"editor.formatOnSave": true,但按下保存的那一刻,代码纹丝不动,满屏缩进依旧狂野。更让人抓狂的是,打开 VS Code 同样的项目却一切正常,一回到 Cursor 就“失忆”。作为日常在多个编辑器之间横跳的人,这类问题我排查过不下十次,踩过的坑从配置路径、默认格式化器、多工具冲突,到 Cursor 自身对工作区设置的特殊处理,基本把能犯的错都犯了一遍。这篇内容就围绕 Cursor 中 Prettier 不生效这件事,把常见的症状、根源、排查顺序和能直接抄的配置全部理清楚。不管你是刚开始用 Cursor 写前端的新人,还是被格式化问题折磨了很久的老手,应该都能在这里找到对应的解法。1. 先给问题分个类:三种症状对应三种完全不同的病根很多人一上来就翻配置、改设置,但其实“不生效”这个词太笼统了。我习惯先把问题分成三类,因为每类的排查方向完全不一样,搞错方向只会越改越乱。1.1 症状一:保存时完全没有格式化动作这是最典型的一种:手写了一段乱七八糟的代码,保存后没有任何反应,缩进、引号、分号该是什么样还是什么样。看起来是“没生效”,实际上大多数时候是 Prettier 压根没有被触发。触发 Prettier 的方式就三种:保存时自动格式化、命令面板手动格式化、右键菜单格式化。如果手动格式化也没反应,那重点怀疑扩展本体的问题;如果只有保存时没反应,那重点怀疑formatOnSave和默认格式化器这两个开关。1.2 症状二:格式化了,但结果和预期不一致这类最迷惑人。保存后代码确实动了,但动得不对:单引号变双引号、分号被删光、缩进变成了 2 空格……很多人以为这是“Prettier 没生效”,其实恰恰相反,是 Prettier 生效了,但被另一套配置或另一个工具“劫持”了,或者它读的根本不是你项目里那份配置文件。这种场景下,问题往往出在“多个格式化器并存”或“个格式器的职责边界没划清”。比如你同时开着 ESLint 的保存自动修复,或者默认格式化器被设成了别的扩展,保存那一刻的最终结果就会被多方势力左右。1.3 症状三:部分文件生效,部分文件不生效还有一类情况很诡异:.js文件好好的,.ts和.tsx纹丝不动;或者项目 A 正常,项目 B 完全失效。这种情况几乎可以断定是“作用域”问题——某个更具体的设置覆盖了全局设置,比如[typescriptreact]语言块的默认格式化器被单独指到了别的地方,或者项目 B 的.prettierrc配置里写了requireConfig之类的限制。先把症状归类,再谈排查。否则你连该查哪一层都不知道,完全是盲人摸象。2. 逐层排查:按这个顺序检查,十分钟定位 Prettier 失效根源既然症状有三种,排查也得有章法。我建议按“扩展运行 → 配置读取 → 格式化器选择 → 触发动作”这条链路依次检查,每层都很简单,但漏掉任何一层都可能让你白忙活半天。2.1 第一层:确认 Prettier 扩展真的在运行虽然听起来像是废话,但我见过太多人“以为装了扩展”结果装错了名字,或者装的是某些改名前的老扩展。打开 Cursor 命令面板(Ctrl+Shift+P或Cmd+Shift+P),输入 “Prettier”,看看下拉列表里有没有这几个命令:Prettier: Format Document(格式化当前文件)Prettier: Show Output(查看 Prettier 扩展的日志输出)如果连这些命令都搜不到,说明扩展根本没被 Cursor 加载。先确认扩展栏里有没有官方扩展(ID 为esbenp.prettier-vscode的那个,发布者名称是 Prettier),装上之后再试一次手动格式化。如果扩展已经装了但命令没反应,可以打开Prettier: Show Output看一下日志。这一步非常有用,Prettier 扩展会把“找不到配置文件”“解析配置出错”“某些文件被 ignore”之类的信息直接写在日志里。我遇到过一次“不生效”,打开日志才发现是配置文件里引用了一个不存在的插件路径,Prettier 直接报错罢工了。2.2 第二层:检查配置文件到底有没有被读取很多情况下,Prettier 不是没有运行,而是运行时没找到项目里的配置,于是用了它自己内置的默认配置。因为默认配置和你项目里的预期往往差别很大(比如有人默认semi: true,有人默认false),看起来就像是“没按我的配置来”,甚至像是“没生效”。这里有一个所有前端人都应该刻在脑子里的机制:Prettier 查找配置时,是从当前文件所在目录开始,逐级往上找的。判定顺序是package.json里的prettier字段、.prettierrc、.prettierrc.json、.prettierrc.js、.prettierrc.cjs、prettier.config.js、prettier.config.cjs等。想确认配置文件有没有被读到,最简单粗暴的办法是直接在终端跑:npx prettier . --check或者只看单个文件:npx prettier src/index.js --check如果命令行输出的格式结果和编辑器里不一样,那基本就是“编辑器没读到你那份配置”或者“编辑器和 CLI 用了不同的配置路径”。另外要注意一个我踩过很多次的坑:项目如果是"type": "module",那.prettierrc.js这种 CommonJS 格式可能不会被正确读取,甚至会直接报错。这种情况下把它改成.prettierrc.cjs,或者干脆改用.prettierrc.json这种纯 JSON 格式,能省下不少麻烦。2.3 第三层:盯住“默认格式化器”和“保存动作”配置读到了、扩展也在运行,但保存时依然没有格式化,那问题基本就出在这一层。Cursor 和 VS Code 一样,有一个editor.defaultFormatter的设置,这个设置可以全局配,也可以按语言配,优先级上语言级 > 工作区级 > 用户级。最容易出问题的场景是:{ "editor.defaultFormatter": "esbenp.prettier-vscode", "[typescriptreact]": { "editor.defaultFormatter": "biome.biome" } }全局明明指定了 Prettier,但某个具体语言的配置把默认格式化器换成了 Biome 或者别的工具。等你打开.tsx文件保存时,Prettier 完全不参与,看起来就是“不生效”。排查方式很简单:打开一个有问题的文件,右键选择 “Format Document With…”,看看列表里默认勾选的是不是 Prettier。不是的话,直接改对应语言块的配置。另外,保存时格式化不只有editor.formatOnSave一个开关。如果你的settings.json里有editor.codeActionsOnSave配置,比如source.fixAll.eslint设为true,那么保存时 ESLint 也会参与进来,它可能在你 Prettier 格式化之前或之后又改了一遍代码,最终结果看起来就像“Prettier 被覆盖了”。2.4 第四层:ESLint、Biome 与其他格式化器的互相拆台如果说前面几层是“Prettier 自己的问题”,那这一层就是“多方协作问题”。现代前端项目通常同时装有 ESLint 和 Prettier,有些新项目还引入了 Biome。它们的功能有重叠:ESLint 本来定位是代码规范检查,但它很多规则(比如indent、quotes)也能改格式;Prettier 专注格式化,但默认规则未必符合团队的 ESLint 规则。当两者同时开启保存时自动修复,顺序就非常关键。实际表现出来的结果往往就是:Prettier 格式化了,然后被 ESLint 再改回去,或者反过来——你看到的最终代码既不完全符合 Prettier,也不完全符合 ESLint,一团乱。个人经验是,最稳的处理方式是:ESLint 只负责“代码规范”,把格式化类的规则关掉,用eslint-config-prettier屏蔽冲突规则;或者用plugin:prettier/recommended,把 Prettier 当成 ESLint 的一条规则跑;保存时只保留一个格式化动作,不要同时开formatOnSave和source.fixAll.eslint。如果你用的是 Biome,那更要注意,Biome 本身就是一个“格式化器 + lint”二合一的工具,和 Prettier 同时开等于两个格式化器互掐。要么全让 Biome 接管,要么干脆别装 Biome 的编辑器扩展。3. 一套可以直接抄的配置模板(含 Cursor 特有细节)排查完之后,就得靠配置把问题彻底解决。下面这套是我个人在实际项目里用着比较稳的组合,分全局、工作区、项目三个层面,你基本可以照着抄,再根据自己的项目微调。3.1 工作区 settings.json:最稳的组合在 Cursor 里打开命令面板,搜索 “Open Workspace Settings (JSON)”,然后在.vscode/settings.json里写入以下内容:{ "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.codeActionsOnSave": { "source.fixAll": "explicit" }, "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[typescriptreact]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[json]": { "editor.defaultFormatter": "esbenp.prettier-vscode" } }这里同时设置全局默认格式化器和各语言块,是为了防止某个语言块被其他工具的配置覆盖。通常 Prettier 扩展被设为默认格式化器后,所有语言都能生效,但单独把前端常用语言列出来,能避免很多边界情况。editor.codeActionsOnSave里的source.fixAll是 VS Code 较新版本的写法,旧版本的写法是"source.fixAll.eslint": true。如果你项目里还用着老配置,建议统一升级成新写法,避免 ESLint 在保存时偷偷改代码。当然,如果你的团队完全靠 ESLint 做格式约束,也可以去掉formatOnSave,只保留 ESLint 修复,但请不要同时开两套格式化链路。3.2 项目级 .prettierrc 与版本锁定编辑器设置只解决“谁来格式化”的问题,格式化出来的结果长什么样,完全由 Prettier 自己的配置决定。项目根目录下建一个.prettierrc.json(我推荐用 JSON 格式,最不容易出编码问题):{ "semi": true, "singleQuote": true, "trailingComma": "all", "tabWidth": 2, "printWidth": 100, "endOfLine": "lf" }cursor 和 vs code 一样,会优先使用项目里node_modules中安装的 prettier 版本,而不是扩展自带的版本。这个机制有好有坏,好处是团队保持版本一致;坏处是如果项目本地安装了很老的版本,某些配置选项可能不兼容,扩展会静默降级。我强烈建议在package.json的devDependencies里固定 Prettier 版本:npm install --save-dev --save-exact prettier锁版本的好处是,CLI 命令、编辑器扩展、CI 流程用的是同一个 Prettier,格式化结果绝不会互相打架。3.3 Cursor 的 Rules、AI 补全与 Prettier 的分工边界这是 Cursor 用户特有的一个问题。Cursor 有全局 Rules、项目 Rules,还可以在 AI 对话里设置偏好,比如“用单引号”“不要分号”。很多人担心 AI 生成的代码不符合团队规范,于是把这些要求塞给 Cursor 的 AI,希望通过它直接生成正确格式的代码。但实际上,AI 生成的代码格式和 Prettier 保存格式化完全是两码事。Rules 影响的是 AI 生成代码的“初始风格”,Prettier 影响的是最终落盘文件的“规范格式”。我的建议是:分工明确——AI 生成交给 Rules 约束大方向,但只要项目里有 Prettier,就始终以保存后的结果为准,不要指望 AI 每次都能精确满足格式化规范。另外提一个 Cursor 特有的体验坑:当你用 Cursor 的 Composer 或 Agent 修改代码时,它会直接写盘,不一定走formatOnSave流程。所以你可能会看到,AI 写出来的代码保存后风格不对,然后你手动按一次格式化才恢复。这不算 Prettier 失效,但确实会让很多人误以为“Cursor 环境下 Prettier 不稳定”。遇到这种情况,直接在 AI 生成后手动触发一次格式化,或者用命令面板里的Format Document就够了。4. 高频问题速查表与我的排查实录前面讲了原理和配置,这里再把实战中遇到频率最高的几个问题整理成速查表,特别适合身边同事跑来问“为什么我 Prettier 不生效”时直接丢给他。4.1 症状-原因-解法速查表症状常见原因排查/解法保存完全没反应,手动格式化也没反应扩展未安装/未启用确认扩展 ID 为 esbenp.prettier-vscode 并启用保存没反应,但手动格式化有效formatOnSave 未开启或设置了 false检查用户级/工作区级 settings.json保存没反应,且代码里没有 Prettier 配置requireConfig: true导致无配置时不格式化把prettier.requireConfig设为 false,或补充 .prettierrcJS 生效,TS/TSX 不生效语言块的 defaultFormatter 被其他工具覆盖检查[typescript]、[typescriptreact]段设置项目 A 正常,项目 B 不生效项目 B 有独立的 .vscode/settings.json 或 .prettierignore对比两个项目的设置与 ignore 文件格式化后代码风格和预期差很多本地 Prettier 版本与项目依赖版本不一致锁版本并确保编辑器使用本地 prettier保存后先格式化又被改乱ESLint 的保存修复与 Prettier 冲突关闭 codeActionsOnSave 中的 fixAll,或使用 eslint-config-prettier打开日志显示配置文件解析失败.prettierrc.js 在 ESM 项目里加载报错改为 .prettierrc.cjs 或 .prettierrc.json某些文件始终不格式化文件被 .prettierignore 或 .gitignore 忽略检查 ignore 文件,确认是否真的放过了目标文件4.2 两个真实排障过程一个是某位前端同事的场景:他项目里所有.js文件格式化正常,唯独.vue文件从来不格式化。当时排查了很久,最后发现是在settings.json里有一行"[vue]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },但是项目里的 Vue 文件不是按标准目录放的,Prettier 扩展没有正确识别。更隐蔽的是,他的settings.json里同时存在两处[vue]配置,后者把前者覆盖了。这说明,多个同名配置块在 settings.json 里出现时,后者会静默覆盖前者,而且不会有任何报错。建议定期检查一下 settings.json 里有没有重复段落。另一个是某团队新引入 Biome 后,发现所有tsx文件保存时不再格式化。原因是他们没在 Cursor 里安装 Biome 扩展,但[typescriptreact]的默认格式化器已经被全局的 Biome 配置接管了,Prettier 自然就成了“局外人”。这类问题处理得很简单——要么卸载 Biome 相关配置,要么明确让某个目录用 Biome,其他目录用 Prettier。4.3 一个很容易被低估的细节:object 内容别背锅很多人排查了半天,最后发现是prettier.requireConfig被设成了true。这个设置的含义是“当项目里没有找到 .prettierrc 等配置文件时,不进行格式化”。它本来是为了防止 Prettier 在未配置的项目里擅自动代码而设计的,但对于新建项目或没有配置文件的脚本类小目录来说,看起来就是“完全没生效”。所以如果你的项目里暂时没有配置文件,又确实想先享受 Prettier 的格式化能力,请确认这个设置没有被打开:{ "prettier.requireConfig": false }当然,如果是在多人协作的正式项目里,我反而建议开true,逼迫每个子项目都带上自己的配置文件,避免有人用全局配置污染整个仓库。5. 写在最后的个人体会排查 Cursor 里 Prettier 不生效这件事,我的心得就一句话:定位永远比修复重要。先把症状分清楚,再按“扩展 → 配置 → 默认格式化器 → 触发动作 → 多工具冲突”这条链路一层层过,大多数问题五分钟内就能找到方向。反而是一上来就乱改设置,今天关掉这个、明天打开那个,最后只会越改越乱。说实话,Cursor 本质上是 VS Code 的分支,所以九成以上的 Prettier 排查方法都能直接平移过来。真正需要注意的只有两点:一是 Cursor 的 AI 对话、Rules 和扩展格式化是三条独立的链路,不要指望 AI 补全的代码未经格式化就直接符合规范;二是 Cursor 版本迭代很快,某些历史版本确实存在过设置面板里改了值但“没生效”的显示层 bug,遇到实在解释不通的奇怪现象,先看一眼是不是版本太旧,更新到最新版往往能解决。另外一个小技巧:在团队项目里,与其依赖每个人在自己的编辑器里手动配formatOnSave,不如在项目里维护好.vscode/settings.json和.prettierrc,并用npx prettier --check .写进 CI。这样哪怕有人用其他编辑器,甚至完全不配置编辑器,最终提交的代码也会被兜底格式化。环境差异带来的“我本地格式很好,一提交就乱了”的经典闹剧,也就能彻底告别了。
每个写过前端的人,大概都经历过这种诡异场景:明明在 Cursor 里装好了 Prettier,settings.json里也写了"editor.formatOnSave": true,但按下保存的那一刻,代码纹丝不动,满屏缩进依旧狂野。更让人抓狂的是,打开 VS Code 同样的项目却一切正常,一回到 Cursor 就“失忆”。作为日常在多个编辑器之间横跳的人,这类问题我排查过不下十次,踩过的坑从配置路径、默认格式化器、多工具冲突,到 Cursor 自身对工作区设置的特殊处理,基本把能犯的错都犯了一遍。这篇内容就围绕 Cursor 中 Prettier 不生效这件事,把常见的症状、根源、排查顺序和能直接抄的配置全部理清楚。不管你是刚开始用 Cursor 写前端的新人,还是被格式化问题折磨了很久的老手,应该都能在这里找到对应的解法。1. 先给问题分个类:三种症状对应三种完全不同的病根很多人一上来就翻配置、改设置,但其实“不生效”这个词太笼统了。我习惯先把问题分成三类,因为每类的排查方向完全不一样,搞错方向只会越改越乱。1.1 症状一:保存时完全没有格式化动作这是最典型的一种:手写了一段乱七八糟的代码,保存后没有任何反应,缩进、引号、分号该是什么样还是什么样。看起来是“没生效”,实际上大多数时候是 Prettier 压根没有被触发。触发 Prettier 的方式就三种:保存时自动格式化、命令面板手动格式化、右键菜单格式化。如果手动格式化也没反应,那重点怀疑扩展本体的问题;如果只有保存时没反应,那重点怀疑formatOnSave和默认格式化器这两个开关。1.2 症状二:格式化了,但结果和预期不一致这类最迷惑人。保存后代码确实动了,但动得不对:单引号变双引号、分号被删光、缩进变成了 2 空格……很多人以为这是“Prettier 没生效”,其实恰恰相反,是 Prettier 生效了,但被另一套配置或另一个工具“劫持”了,或者它读的根本不是你项目里那份配置文件。这种场景下,问题往往出在“多个格式化器并存”或“个格式器的职责边界没划清”。比如你同时开着 ESLint 的保存自动修复,或者默认格式化器被设成了别的扩展,保存那一刻的最终结果就会被多方势力左右。1.3 症状三:部分文件生效,部分文件不生效还有一类情况很诡异:.js文件好好的,.ts和.tsx纹丝不动;或者项目 A 正常,项目 B 完全失效。这种情况几乎可以断定是“作用域”问题——某个更具体的设置覆盖了全局设置,比如[typescriptreact]语言块的默认格式化器被单独指到了别的地方,或者项目 B 的.prettierrc配置里写了requireConfig之类的限制。先把症状归类,再谈排查。否则你连该查哪一层都不知道,完全是盲人摸象。2. 逐层排查:按这个顺序检查,十分钟定位 Prettier 失效根源既然症状有三种,排查也得有章法。我建议按“扩展运行 → 配置读取 → 格式化器选择 → 触发动作”这条链路依次检查,每层都很简单,但漏掉任何一层都可能让你白忙活半天。2.1 第一层:确认 Prettier 扩展真的在运行虽然听起来像是废话,但我见过太多人“以为装了扩展”结果装错了名字,或者装的是某些改名前的老扩展。打开 Cursor 命令面板(Ctrl+Shift+P或Cmd+Shift+P),输入 “Prettier”,看看下拉列表里有没有这几个命令:Prettier: Format Document(格式化当前文件)Prettier: Show Output(查看 Prettier 扩展的日志输出)如果连这些命令都搜不到,说明扩展根本没被 Cursor 加载。先确认扩展栏里有没有官方扩展(ID 为esbenp.prettier-vscode的那个,发布者名称是 Prettier),装上之后再试一次手动格式化。如果扩展已经装了但命令没反应,可以打开Prettier: Show Output看一下日志。这一步非常有用,Prettier 扩展会把“找不到配置文件”“解析配置出错”“某些文件被 ignore”之类的信息直接写在日志里。我遇到过一次“不生效”,打开日志才发现是配置文件里引用了一个不存在的插件路径,Prettier 直接报错罢工了。2.2 第二层:检查配置文件到底有没有被读取很多情况下,Prettier 不是没有运行,而是运行时没找到项目里的配置,于是用了它自己内置的默认配置。因为默认配置和你项目里的预期往往差别很大(比如有人默认semi: true,有人默认false),看起来就像是“没按我的配置来”,甚至像是“没生效”。这里有一个所有前端人都应该刻在脑子里的机制:Prettier 查找配置时,是从当前文件所在目录开始,逐级往上找的。判定顺序是package.json里的prettier字段、.prettierrc、.prettierrc.json、.prettierrc.js、.prettierrc.cjs、prettier.config.js、prettier.config.cjs等。想确认配置文件有没有被读到,最简单粗暴的办法是直接在终端跑:npx prettier . --check或者只看单个文件:npx prettier src/index.js --check如果命令行输出的格式结果和编辑器里不一样,那基本就是“编辑器没读到你那份配置”或者“编辑器和 CLI 用了不同的配置路径”。另外要注意一个我踩过很多次的坑:项目如果是"type": "module",那.prettierrc.js这种 CommonJS 格式可能不会被正确读取,甚至会直接报错。这种情况下把它改成.prettierrc.cjs,或者干脆改用.prettierrc.json这种纯 JSON 格式,能省下不少麻烦。2.3 第三层:盯住“默认格式化器”和“保存动作”配置读到了、扩展也在运行,但保存时依然没有格式化,那问题基本就出在这一层。Cursor 和 VS Code 一样,有一个editor.defaultFormatter的设置,这个设置可以全局配,也可以按语言配,优先级上语言级 > 工作区级 > 用户级。最容易出问题的场景是:{ "editor.defaultFormatter": "esbenp.prettier-vscode", "[typescriptreact]": { "editor.defaultFormatter": "biome.biome" } }全局明明指定了 Prettier,但某个具体语言的配置把默认格式化器换成了 Biome 或者别的工具。等你打开.tsx文件保存时,Prettier 完全不参与,看起来就是“不生效”。排查方式很简单:打开一个有问题的文件,右键选择 “Format Document With…”,看看列表里默认勾选的是不是 Prettier。不是的话,直接改对应语言块的配置。另外,保存时格式化不只有editor.formatOnSave一个开关。如果你的settings.json里有editor.codeActionsOnSave配置,比如source.fixAll.eslint设为true,那么保存时 ESLint 也会参与进来,它可能在你 Prettier 格式化之前或之后又改了一遍代码,最终结果看起来就像“Prettier 被覆盖了”。2.4 第四层:ESLint、Biome 与其他格式化器的互相拆台如果说前面几层是“Prettier 自己的问题”,那这一层就是“多方协作问题”。现代前端项目通常同时装有 ESLint 和 Prettier,有些新项目还引入了 Biome。它们的功能有重叠:ESLint 本来定位是代码规范检查,但它很多规则(比如indent、quotes)也能改格式;Prettier 专注格式化,但默认规则未必符合团队的 ESLint 规则。当两者同时开启保存时自动修复,顺序就非常关键。实际表现出来的结果往往就是:Prettier 格式化了,然后被 ESLint 再改回去,或者反过来——你看到的最终代码既不完全符合 Prettier,也不完全符合 ESLint,一团乱。个人经验是,最稳的处理方式是:ESLint 只负责“代码规范”,把格式化类的规则关掉,用eslint-config-prettier屏蔽冲突规则;或者用plugin:prettier/recommended,把 Prettier 当成 ESLint 的一条规则跑;保存时只保留一个格式化动作,不要同时开formatOnSave和source.fixAll.eslint。如果你用的是 Biome,那更要注意,Biome 本身就是一个“格式化器 + lint”二合一的工具,和 Prettier 同时开等于两个格式化器互掐。要么全让 Biome 接管,要么干脆别装 Biome 的编辑器扩展。3. 一套可以直接抄的配置模板(含 Cursor 特有细节)排查完之后,就得靠配置把问题彻底解决。下面这套是我个人在实际项目里用着比较稳的组合,分全局、工作区、项目三个层面,你基本可以照着抄,再根据自己的项目微调。3.1 工作区 settings.json:最稳的组合在 Cursor 里打开命令面板,搜索 “Open Workspace Settings (JSON)”,然后在.vscode/settings.json里写入以下内容:{ "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.codeActionsOnSave": { "source.fixAll": "explicit" }, "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[typescriptreact]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[json]": { "editor.defaultFormatter": "esbenp.prettier-vscode" } }这里同时设置全局默认格式化器和各语言块,是为了防止某个语言块被其他工具的配置覆盖。通常 Prettier 扩展被设为默认格式化器后,所有语言都能生效,但单独把前端常用语言列出来,能避免很多边界情况。editor.codeActionsOnSave里的source.fixAll是 VS Code 较新版本的写法,旧版本的写法是"source.fixAll.eslint": true。如果你项目里还用着老配置,建议统一升级成新写法,避免 ESLint 在保存时偷偷改代码。当然,如果你的团队完全靠 ESLint 做格式约束,也可以去掉formatOnSave,只保留 ESLint 修复,但请不要同时开两套格式化链路。3.2 项目级 .prettierrc 与版本锁定编辑器设置只解决“谁来格式化”的问题,格式化出来的结果长什么样,完全由 Prettier 自己的配置决定。项目根目录下建一个.prettierrc.json(我推荐用 JSON 格式,最不容易出编码问题):{ "semi": true, "singleQuote": true, "trailingComma": "all", "tabWidth": 2, "printWidth": 100, "endOfLine": "lf" }cursor 和 vs code 一样,会优先使用项目里node_modules中安装的 prettier 版本,而不是扩展自带的版本。这个机制有好有坏,好处是团队保持版本一致;坏处是如果项目本地安装了很老的版本,某些配置选项可能不兼容,扩展会静默降级。我强烈建议在package.json的devDependencies里固定 Prettier 版本:npm install --save-dev --save-exact prettier锁版本的好处是,CLI 命令、编辑器扩展、CI 流程用的是同一个 Prettier,格式化结果绝不会互相打架。3.3 Cursor 的 Rules、AI 补全与 Prettier 的分工边界这是 Cursor 用户特有的一个问题。Cursor 有全局 Rules、项目 Rules,还可以在 AI 对话里设置偏好,比如“用单引号”“不要分号”。很多人担心 AI 生成的代码不符合团队规范,于是把这些要求塞给 Cursor 的 AI,希望通过它直接生成正确格式的代码。但实际上,AI 生成的代码格式和 Prettier 保存格式化完全是两码事。Rules 影响的是 AI 生成代码的“初始风格”,Prettier 影响的是最终落盘文件的“规范格式”。我的建议是:分工明确——AI 生成交给 Rules 约束大方向,但只要项目里有 Prettier,就始终以保存后的结果为准,不要指望 AI 每次都能精确满足格式化规范。另外提一个 Cursor 特有的体验坑:当你用 Cursor 的 Composer 或 Agent 修改代码时,它会直接写盘,不一定走formatOnSave流程。所以你可能会看到,AI 写出来的代码保存后风格不对,然后你手动按一次格式化才恢复。这不算 Prettier 失效,但确实会让很多人误以为“Cursor 环境下 Prettier 不稳定”。遇到这种情况,直接在 AI 生成后手动触发一次格式化,或者用命令面板里的Format Document就够了。4. 高频问题速查表与我的排查实录前面讲了原理和配置,这里再把实战中遇到频率最高的几个问题整理成速查表,特别适合身边同事跑来问“为什么我 Prettier 不生效”时直接丢给他。4.1 症状-原因-解法速查表症状常见原因排查/解法保存完全没反应,手动格式化也没反应扩展未安装/未启用确认扩展 ID 为 esbenp.prettier-vscode 并启用保存没反应,但手动格式化有效formatOnSave 未开启或设置了 false检查用户级/工作区级 settings.json保存没反应,且代码里没有 Prettier 配置requireConfig: true导致无配置时不格式化把prettier.requireConfig设为 false,或补充 .prettierrcJS 生效,TS/TSX 不生效语言块的 defaultFormatter 被其他工具覆盖检查[typescript]、[typescriptreact]段设置项目 A 正常,项目 B 不生效项目 B 有独立的 .vscode/settings.json 或 .prettierignore对比两个项目的设置与 ignore 文件格式化后代码风格和预期差很多本地 Prettier 版本与项目依赖版本不一致锁版本并确保编辑器使用本地 prettier保存后先格式化又被改乱ESLint 的保存修复与 Prettier 冲突关闭 codeActionsOnSave 中的 fixAll,或使用 eslint-config-prettier打开日志显示配置文件解析失败.prettierrc.js 在 ESM 项目里加载报错改为 .prettierrc.cjs 或 .prettierrc.json某些文件始终不格式化文件被 .prettierignore 或 .gitignore 忽略检查 ignore 文件,确认是否真的放过了目标文件4.2 两个真实排障过程一个是某位前端同事的场景:他项目里所有.js文件格式化正常,唯独.vue文件从来不格式化。当时排查了很久,最后发现是在settings.json里有一行"[vue]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },但是项目里的 Vue 文件不是按标准目录放的,Prettier 扩展没有正确识别。更隐蔽的是,他的settings.json里同时存在两处[vue]配置,后者把前者覆盖了。这说明,多个同名配置块在 settings.json 里出现时,后者会静默覆盖前者,而且不会有任何报错。建议定期检查一下 settings.json 里有没有重复段落。另一个是某团队新引入 Biome 后,发现所有tsx文件保存时不再格式化。原因是他们没在 Cursor 里安装 Biome 扩展,但[typescriptreact]的默认格式化器已经被全局的 Biome 配置接管了,Prettier 自然就成了“局外人”。这类问题处理得很简单——要么卸载 Biome 相关配置,要么明确让某个目录用 Biome,其他目录用 Prettier。4.3 一个很容易被低估的细节:object 内容别背锅很多人排查了半天,最后发现是prettier.requireConfig被设成了true。这个设置的含义是“当项目里没有找到 .prettierrc 等配置文件时,不进行格式化”。它本来是为了防止 Prettier 在未配置的项目里擅自动代码而设计的,但对于新建项目或没有配置文件的脚本类小目录来说,看起来就是“完全没生效”。所以如果你的项目里暂时没有配置文件,又确实想先享受 Prettier 的格式化能力,请确认这个设置没有被打开:{ "prettier.requireConfig": false }当然,如果是在多人协作的正式项目里,我反而建议开true,逼迫每个子项目都带上自己的配置文件,避免有人用全局配置污染整个仓库。5. 写在最后的个人体会排查 Cursor 里 Prettier 不生效这件事,我的心得就一句话:定位永远比修复重要。先把症状分清楚,再按“扩展 → 配置 → 默认格式化器 → 触发动作 → 多工具冲突”这条链路一层层过,大多数问题五分钟内就能找到方向。反而是一上来就乱改设置,今天关掉这个、明天打开那个,最后只会越改越乱。说实话,Cursor 本质上是 VS Code 的分支,所以九成以上的 Prettier 排查方法都能直接平移过来。真正需要注意的只有两点:一是 Cursor 的 AI 对话、Rules 和扩展格式化是三条独立的链路,不要指望 AI 补全的代码未经格式化就直接符合规范;二是 Cursor 版本迭代很快,某些历史版本确实存在过设置面板里改了值但“没生效”的显示层 bug,遇到实在解释不通的奇怪现象,先看一眼是不是版本太旧,更新到最新版往往能解决。另外一个小技巧:在团队项目里,与其依赖每个人在自己的编辑器里手动配formatOnSave,不如在项目里维护好.vscode/settings.json和.prettierrc,并用npx prettier --check .写进 CI。这样哪怕有人用其他编辑器,甚至完全不配置编辑器,最终提交的代码也会被兜底格式化。环境差异带来的“我本地格式很好,一提交就乱了”的经典闹剧,也就能彻底告别了。