Prettier 配置文件完全指南:格式优先级、overrides 定制与 EditorConfig 集成
【免费下载链接】prettierPrettier is an opinionated code formatter.项目地址: https://gitcode.com/gh_mirrors/pr/prettier
本文以 Prettier 官方文档《Configuration File》为核心,系统讲解 Prettier 的全部配置文件形态及其查找优先级、配置文件在各目录树中的解析流程,并结合当前仓库src/config/下的真实源码,深入剖析overrides匹配规则、parser选项的正确用法,以及.editorconfig到 Prettier 选项的转换逻辑。读完后你可以为项目选择合适的配置文件格式,按文件类型精细定制格式化规则,并理解每一项配置在源码中是如何被加载与合并的。
配置文件格式与优先级
Prettier 支持多种配置文件,按优先级从高到低依次为:
package.json中的"prettier"键,或package.yaml文件中的prettier字段;- 以 JSON 或 YAML 编写的
.prettierrc文件; .prettierrc.json、.prettierrc.yml、.prettierrc.yaml或.prettierrc.json5文件;- 通过
export default或module.exports(取决于package.json中的type值)导出对象的.prettierrc.js、prettier.config.js、.prettierrc.ts或prettier.config.ts文件; - 通过
export default导出对象的.prettierrc.mjs、prettier.config.mjs、.prettierrc.mts或prettier.config.mts文件; - 通过
module.exports导出对象的.prettierrc.cjs、prettier.config.cjs、.prettierrc.cts或prettier.config.cts文件; .prettierrc.toml文件。
这一优先级顺序并非只在文档中约定,而是直接体现在源码中。src/config/prettier-config/config-searcher.js 里的CONFIG_FILES数组按完全相同的顺序排列了上述所有候选文件名,源码中还留有注释 “Please keep this order sync with docs, docs/configuration.md”,说明文档与代码是刻意保持同步的。值得注意的是:
- 对
package.json/package.yaml,源码会先尝试读取其中的prettier字段,只有字段存在时该文件才会被视为有效配置(filter返回Boolean(await loadConfigFromPackageJson(file))); - 在 src/config/prettier-config/loaders.js 中,每种扩展名对应一个加载器:
.json用parse-json解析,.json5用 JSON5,.toml用smol-toml,.yaml/.yml及无扩展名的.prettierrc则复用 Prettier 自身的 YAML 插件(__parsePrettierYamlConfig)来解析,而.js/.mjs/.cjs/.ts/.mts/.cts统一通过import()动态导入后取module.default; - 一个细节:
loadConfigFromPackageJson在 Bun 运行时会启用特殊分支(readBunPackageJson),因为 Bun 允许package.json包含注释和尾逗号,纯 JSON 解析失败后会退化为import()加载。
配置文件内可用的选项与 API options 完全一致。
配置文件的查找流程
Prettier 会从被格式化文件所在的位置开始,沿目录树逐级向上查找,直到找到(或找不到)配置文件。从源码看,入口在 src/config/resolve-config.js:
loadPrettierConfig先取path.dirname(path.resolve(file))作为搜索起点,再调用searchPrettierConfig(定义于 src/config/prettier-config/index.js)沿目录树向上查找;搜索函数与加载结果均带内存缓存(searchCache/loadCache两个Map),CLI 批量格式化时可减少重复的文件系统访问。
Prettier有意不支持任何形式的“全局配置”。这样做的目的是:当项目被拷贝到另一台电脑时,Prettier 的行为保持不变,从而保证团队里每个人得到一致的格式化结果。
TypeScript 配置文件的运行前提
使用.ts/.mts/.cts配置文件需要 Node.js ≥ 22.6.0;在 Node.js v24.3.0 之前的版本上还需要显式开启类型剥离,例如:
node --experimental-strip-types node_modules/prettier/bin/prettier.cjs . --write或:
NODE_OPTIONS="--experimental-strip-types" prettier . --write外部共享配置与插件路径解析
源码中还体现了两个文档未展开、但对配置管理很有用的行为(均来自 src/config/prettier-config/load-config.js 与 src/config/resolve-config.js):
- 当配置内容是一个字符串时(例如
package.json里写"prettier": "my-config-package"),Prettier 会把它当作外部配置包或文件加载——先尝试require(),失败后再尝试import()(见 load-external-config.js)。这为多项目共享同一份 Prettier 配置提供了基础; - 配置中
plugins数组里的相对路径(以.开头)会以配置文件所在目录为基准解析为绝对路径; - 配置对象中的
$schema字段在加载完成后会被loadConfig主动delete,因此写$schema不会影响格式化行为。
基础配置示例
以下是各格式的最小可用配置(与官方文档示例一致):
JSON:
// .prettierrc.json or .prettierrc { "trailingComma": "es5", "tabWidth": 4, "semi": false, "singleQuote": true }JS(ES Modules):
// prettier.config.mjs, .prettierrc.mjs, prettier.config.js, or .prettierrc.js /** * @type {import("prettier").Config} */ const config = { trailingComma: "es5", tabWidth: 4, semi: false, singleQuote: true, }; export default config;JS(CommonJS):
// prettier.config.cjs, .prettierrc.cjs, prettier.config.js, or .prettierrc.js /** * @type {import("prettier").Config} */ const config = { trailingComma: "es5", tabWidth: 4, semi: false, singleQuote: true, }; module.exports = config;TypeScript(ES Modules):
// prettier.config.mts, .prettierrc.mts, prettier.config.ts, or .prettierrc.ts import { type Config } from "prettier"; const config: Config = { trailingComma: "none", }; export default config;TypeScript(CommonJS):
// prettier.config.cts, .prettierrc.cts, prettier.config.ts, or .prettierrc.ts import { type Config } from "prettier"; const config: Config = { trailingComma: "none", }; module.exports = config;YAML:
# .prettierrc, .prettierrc.yml, or .prettierrc.yaml trailingComma: "es5" tabWidth: 4 semi: false singleQuote: trueTOML:
# .prettierrc.toml trailingComma = "es5" tabWidth = 4 semi = false singleQuote = true如果你希望编辑器对配置文件做 JSON Schema 校验,官方在 SchemaStore 提供了prettierrc的 JSON Schema,可通过$schema字段引入(Prettier 加载配置时会自动移除该字段,不影响行为)。仓库根目录的 prettier.config.js 就是一个真实的 JS 配置文件实例,可以直接参考其写法。
使用 overrides 按文件定制配置
overrides允许你对特定扩展名、文件夹或具体文件使用不同的配置。
JSON:
// .prettierrc { "semi": false, "overrides": [ { "files": ["*.test.js"], "options": { "semi": true } }, { "files": ["*.html", "legacy/**/*.js"], "options": { "tabWidth": 4 } } ] }YAML:
// .prettierrc semi: false overrides: - files: - "*.test.js" options: semi: true - files: - "*.html" - "legacy/**/*.js" options: tabWidth: 4约束:每个 override 必须提供files,可以是字符串或字符串数组;可选提供excludeFiles用于排除某些文件,同样支持字符串或字符串数组。
结合源码 src/config/resolve-config.js 可以更精确地理解匹配规则(mergeOverrides与pathMatchesGlobs):
- 匹配用的是相对路径:
path.relative(配置文件所在目录, 目标文件),因此overrides中的路径模式是相对于配置文件所在目录计算的; - 模式被分为两类分别处理:不含
/的模式(如*.test.js)以basename方式匹配文件名,可匹配任意深度;含/的模式(如legacy/**/*.js)则按相对路径完整匹配; excludeFiles直接作为 micromatch 的ignore参数传入,命中的文件即使匹配了files也不会应用该 override;- 多个 override 按数组顺序依次
Object.assign,后面的规则会覆盖前面的同名选项。
正确设置 parser 选项
默认情况下,Prettier 根据文件扩展名自动推断要使用的解析器。配合overrides,你可以教 Prettier 如何解析它不认识的扩展名。例如,为了让 Prettier 格式化它自己的.prettierrc文件:
// .prettierrc { "overrides": [ { "files": [".prettierrc"], "options": { "parser": "json" } } ] }也可以把.js文件的默认babel解析器换成flow:
// .prettierrc { "overrides": [ { "files": ["*.js"], "options": { "parser": "flow" } } ] }注意:绝不要把parser写在配置的顶层,只应在overrides内部使用。否则相当于禁用了 Prettier 基于文件扩展名的自动解析器推断,Prettier 会对你指定的所有文件都使用同一个解析器——包括把 CSS 文件当 JavaScript 解析这种毫无意义的情况。
与 EditorConfig 集成
如果项目里存在.editorconfig文件,Prettier 会解析它并把其中的属性转换成对应的 Prettier 配置;这些转换后的配置会被.prettierrc等 Prettier 配置文件覆盖(在 resolve-config.js 中,合并顺序是{ ...editorConfigured, ...mergeOverrides(result, filePath) },即 Prettier 配置在后、优先级更高)。
需要注意:与 EditorConfig 规范不同,Prettier 对.editorconfig的搜索到项目根目录就会停止,不会继续向上。从源码看,项目根由 src/config/find-project-root.js 中的版本控制标记(.git文件或.hg目录)判定,.editorconfig解析(src/config/editorconfig/index.js)会把该根目录作为root传给解析器。
下面是带注释的.editorconfig示例,说明各属性如何映射到 Prettier 行为:
// .editorconfig # 阻止编辑器继续向父目录查找 .editorconfig 文件 # root = true [*] # Prettier 不可配置的行为(固定行为) charset = utf-8 insert_final_newline = true # 注意:Prettier 不会清理模板字符串内的行尾空白,但编辑器可能会。 # trim_trailing_whitespace = true # 可配置的 Prettier 行为 # (如果你的 Prettier 配置不同,请修改这些值) end_of_line = lf indent_style = space indent_size = 2 max_line_length = 80如果使用默认选项,可以直接复制下面这份.editorconfig:
// .editorconfig [*] charset = utf-8 insert_final_newline = true end_of_line = lf indent_style = space indent_size = 2 max_line_length = 80从 src/config/editorconfig/editorconfig-to-prettier.js 的转换实现看,映射规则为:
.editorconfig属性 | Prettier 选项 | 规则说明 |
|---|---|---|
indent_style = space/tab,或indent_size = tab | useTabs | space→false,tab→true |
indent_size/tab_width(正整数) | tabWidth | 当useTabs === false时优先取indent_size,否则取tab_width |
max_line_length(正整数 /off) | printWidth | 正整数直接映射;off映射为Infinity |
quote_type = single/double | singleQuote | 源码注释标明这是未写入 EditorConfig 规范文档的扩展特性 |
end_of_line = lf/crlf/cr | endOfLine | 三个取值原样透传 |
这些映射有对应的单元测试覆盖,见 tests/unit/editorconfig-to-prettier.js,例如验证了indent_style: "tab"时tab_width: 8优先生效、indent_style: "space"时indent_size生效等边界情况。
此外,Prettier CLI 提供了editorconfig开关(见 src/cli/cli-options.evaluate.js 中的选项定义,描述为 “Take .editorconfig into account when parsing configuration”),传入--no-editorconfig即可在命令行层面关闭 EditorConfig 参与配置解析;CLI 在 src/cli/options/get-options-for-file.js 中会把该开关透传给resolveConfig。
小结
Prettier 的配置体系可以概括为三层:配置文件形态(JSON/YAML/TOML/JSON5/JS/TS,按固定优先级查找)、overrides提供按文件的精细覆盖(基于相对于配置目录的 glob 匹配)、.editorconfig作为更底层的兜底来源。三者最终在resolveConfig中按 “EditorConfig → Prettier 配置 → 匹配的 overrides” 的顺序合并出每个文件的最终选项。理解了 src/config/ 下的这套查找、加载与合并逻辑后,你可以为不同规模的项目选择最合适的配置组织方式,并准确预判每条规则的实际生效范围。
【免费下载链接】prettierPrettier is an opinionated code formatter.项目地址: https://gitcode.com/gh_mirrors/pr/prettier
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考