Skip to content

Prettier 使用配置指南

Prettier 是一个代码格式化工具,支持多种语言,专注于代码格式的统一:

  • 自动格式化代码
  • 统一代码风格
  • 可配置的格式化规则

什么是 Prettier?

Prettier 是一个"有主见"的代码格式化工具,它通过解析代码并重新格式化来确保代码风格的一致性。它支持 JavaScript、TypeScript、CSS、JSON、Markdown 等多种语言。

安装

安装 Prettier

bash
# 安装 Prettier
npm install --save-dev prettier

# 或使用 pnpm
pnpm add -D prettier

# 或使用 yarn
yarn add -D prettier

安装集成插件

bash
# 与 ESLint 集成
npm install --save-dev eslint-config-prettier eslint-plugin-prettier

# Vue 项目推荐
npm install --save-dev @vue/eslint-config-prettier

配置文件

.prettierrc.js 配置示例

javascript
module.exports = {
  // 每行最大字符数
  printWidth: 100,
  
  // 缩进空格数
  tabWidth: 2,
  
  // 使用空格而不是 Tab
  useTabs: false,
  
  // 语句末尾添加分号
  semi: true,
  
  // 使用单引号
  singleQuote: true,
  
  // 对象属性的引号使用
  quoteProps: 'as-needed',
  
  // JSX 中使用单引号
  jsxSingleQuote: false,
  
  // 尾随逗号
  trailingComma: 'es5',
  
  // 对象大括号内空格
  bracketSpacing: true,
  
  // JSX 标签的反尖括号需要换行
  bracketSameLine: false,
  
  // 箭头函数参数括号
  arrowParens: 'always',
  
  // 换行符
  endOfLine: 'lf',
  
  // HTML 空白敏感性
  htmlWhitespaceSensitivity: 'css',
  
  // Vue 文件中的 script 和 style 标签缩进
  vueIndentScriptAndStyle: false,
}

.prettierrc.json 配置示例

json
{
  "printWidth": 100,
  "tabWidth": 2,
  "useTabs": false,
  "semi": true,
  "singleQuote": true,
  "quoteProps": "as-needed",
  "jsxSingleQuote": false,
  "trailingComma": "es5",
  "bracketSpacing": true,
  "bracketSameLine": false,
  "arrowParens": "always",
  "endOfLine": "lf",
  "htmlWhitespaceSensitivity": "css",
  "vueIndentScriptAndStyle": false
}

.prettierrc.yaml 配置示例

yaml
printWidth: 100
tabWidth: 2
useTabs: false
semi: true
singleQuote: true
quoteProps: as-needed
jsxSingleQuote: false
trailingComma: 'es5'
bracketSpacing: true
bracketSameLine: false
arrowParens: always
endOfLine: lf
htmlWhitespaceSensitivity: css
vueIndentScriptAndStyle: false

.prettierrc.yaml 配置示例(简洁版)

yaml
semi: true
singleQuote: true
tabWidth: 2
trailingComma: 'es5'
printWidth: 100
arrowParens: always
endOfLine: lf

配置选项说明

printWidth

每行最大字符数,超过会自动换行。

javascript
// printWidth: 80(默认)
const longVariableName = someVeryLongFunctionName(parameter1, parameter2, parameter3);

// printWidth: 100
const longVariableName = someVeryLongFunctionName(
  parameter1,
  parameter2,
  parameter3
);

tabWidth

缩进使用的空格数。

javascript
// tabWidth: 2
if (condition) {
  doSomething();
}

// tabWidth: 4
if (condition) {
    doSomething();
}

useTabs

是否使用 Tab 代替空格。

javascript
// useTabs: false(使用空格)
if (condition) {
  doSomething();
}

// useTabs: true(使用 Tab)
if (condition) {
	doSomething();
}

semi

是否在语句末尾添加分号。

javascript
// semi: true
const name = 'Tom';

// semi: false
const name = 'Tom'

singleQuote

是否使用单引号。

javascript
// singleQuote: true
const name = 'Tom';

// singleQuote: false
const name = "Tom";

quoteProps

对象属性的引号使用方式。

javascript
// quoteProps: 'as-needed'(仅在需要时使用)
const obj = {
  name: 'Tom',
  'first-name': 'Tom',  // 需要引号
  age: 20
};

// quoteProps: 'always'(总是使用)
const obj = {
  'name': 'Tom',
  'first-name': 'Tom',
  'age': 20
};

trailingComma

尾随逗号的使用方式。

javascript
// trailingComma: 'es5'(ES5 兼容)
const arr = [
  1,
  2,
  3
];

const obj = {
  a: 1,
  b: 2
};

// trailingComma: 'all'(所有地方都使用)
const arr = [
  1,
  2,
  3,  // 有逗号
];

const obj = {
  a: 1,
  b: 2,  // 有逗号
};

bracketSpacing

对象大括号内是否有空格。

javascript
// bracketSpacing: true
const obj = { a: 1, b: 2 };

// bracketSpacing: false
const obj = {a: 1, b: 2};

arrowParens

箭头函数参数是否使用括号。

javascript
// arrowParens: 'always'
const fn = (x) => x * 2;

// arrowParens: 'avoid'
const fn = x => x * 2;

endOfLine

换行符类型。

javascript
// endOfLine: 'lf'(Unix)
// endOfLine: 'crlf'(Windows)
// endOfLine: 'cr'(旧 Mac)
// endOfLine: 'auto'(保持原样)

.prettierignore 文件

创建 .prettierignore 文件指定不需要格式化的文件:

gitignore
# 依赖
node_modules
package-lock.json
pnpm-lock.yaml
yarn.lock

# 构建产物
dist
build
*.min.js

# 日志
*.log

# 配置文件
*.config.js
tsconfig.json
.prettierrc.js
.eslintrc.js

# 其他
.DS_Store
.env
coverage

Vue 项目配置

Vue 3 + TypeScript + Vite

json
// .prettierrc.json
{
  "semi": true,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "es5",
  "printWidth": 100,
  "arrowParens": "always",
  "endOfLine": "lf",
  "vueIndentScriptAndStyle": false
}

vueIndentScriptAndStyle

控制 Vue 文件中的 <script><style> 标签是否缩进。

vue
<!-- vueIndentScriptAndStyle: false -->
<template>
  <div>Hello</div>
</template>
<script>
export default {
  name: 'App'
}
</script>
<style>
.app {
  color: red;
}
</style>

<!-- vueIndentScriptAndStyle: true -->
<template>
  <div>Hello</div>
</template>
  <script>
    export default {
      name: 'App'
    }
  </script>
  <style>
    .app {
      color: red;
    }
  </style>

React 项目配置

json
// .prettierrc.json
{
  "semi": true,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "es5",
  "printWidth": 100,
  "arrowParens": "always",
  "bracketSpacing": true,
  "jsxSingleQuote": false,
  "endOfLine": "lf"
}

与 ESLint 集成

解决冲突

ESLint 和 Prettier 可能会有规则冲突,需要正确配置。

javascript
// .eslintrc.js
module.exports = {
  extends: [
    'eslint:recommended',
    'prettier', // 必须放在最后,关闭与 Prettier 冲突的规则
  ],
  plugins: ['prettier'],
  rules: {
    'prettier/prettier': 'error', // 将 Prettier 的格式化问题作为 ESLint 错误
  },
}

推荐安装的包

bash
npm install --save-dev eslint-config-prettier eslint-plugin-prettier
  • eslint-config-prettier:关闭 ESLint 中与 Prettier 冲突的规则
  • eslint-plugin-prettier:将 Prettier 作为 ESLint 规则运行

在 VSCode 中配置

创建 .vscode/settings.json

json
{
  // Prettier 配置
  "prettier.enable": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  
  // 保存时自动格式化
  "editor.formatOnSave": true,
  
  // 文件类型特定配置
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[vue]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[json]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[css]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[scss]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[markdown]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  }
}

在 package.json 中添加脚本

json
{
  "scripts": {
    "format": "prettier --write \"**/*.{js,jsx,ts,tsx,vue,json,css,scss,md}\"",
    "format:check": "prettier --check \"**/*.{js,jsx,ts,tsx,vue,json,css,scss,md}\"",
    "format:staged": "prettier --write"
  }
}

使用说明

bash
# 格式化所有文件
npm run format

# 检查格式(不修改文件)
npm run format:check

# 格式化指定文件
npx prettier --write src/**/*.js

实际应用场景

1. Git Hooks 集成

使用 husky 和 lint-staged 在提交前自动格式化:

bash
# 安装依赖
npm install --save-dev husky lint-staged
json
// package.json
{
  "lint-staged": {
    "*.{js,jsx,ts,tsx,vue}": [
      "prettier --write"
    ],
    "*.{json,css,scss,md}": [
      "prettier --write"
    ]
  }
}
bash
# 初始化 husky
npx husky install

# 添加 pre-commit hook
npx husky add .husky/pre-commit "npx lint-staged"

2. CI/CD 集成

在 GitHub Actions 中配置:

yaml
# .github/workflows/format.yml
name: Format Check

on: [push, pull_request]

jobs:
  format:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
      - run: npm ci
      - run: npm run format:check

3. 选择性格式化

格式化特定文件或目录:

bash
# 格式化 src 目录下的所有文件
npx prettier --write "src/**/*"

# 格式化单个文件
npx prettier --write src/index.js

# 格式化多个文件类型
npx prettier --write "src/**/*.{js,ts,vue}"

常见问题

1. ESLint 和 Prettier 冲突

问题:格式化后 ESLint 报错

解决方案

  • 确保 eslint-config-prettier 在 extends 数组的最后
  • 使用 eslint-plugin-prettier 将 Prettier 作为 ESLint 规则运行

2. 不同编辑器格式化不一致

问题:不同编辑器格式化结果不同

解决方案

  • 统一使用 .prettierrc 配置文件
  • 确保编辑器安装了 Prettier 插件
  • .editorconfig 中配置编辑器设置

3. 格式化后 Git 变更过多

问题:格式化导致大量文件变更

解决方案

  • 首次格式化使用单独提交
  • 使用 .prettierignore 排除不需要格式化的文件
  • 在项目初期就配置好格式化规则

4. HTML 标签被格式化

问题:HTML 标签被意外格式化

解决方案

  • 使用 htmlWhitespaceSensitivity: 'css' 选项
  • .prettierignore 中排除 HTML 文件(如果需要)

最佳实践

  1. 统一配置:团队使用相同的配置文件
  2. 版本控制:将 .prettierrc.prettierignore 提交到 Git
  3. 渐进式引入:在项目初期就配置好格式化规则
  4. 自动化:使用 Git Hooks 和 CI/CD 自动格式化
  5. 文档化:记录重要的配置决策和原因
  6. 定期更新:保持 Prettier 版本更新

推荐配置模板

基础配置

json
// .prettierrc.json
{
  "semi": true,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "es5",
  "printWidth": 100,
  "arrowParens": "always",
  "endOfLine": "lf"
}

Vue 项目配置

json
// .prettierrc.json
{
  "semi": true,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "es5",
  "printWidth": 100,
  "arrowParens": "always",
  "endOfLine": "lf",
  "vueIndentScriptAndStyle": false
}

React 项目配置

json
// .prettierrc.json
{
  "semi": true,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "es5",
  "printWidth": 100,
  "arrowParens": "always",
  "bracketSpacing": true,
  "jsxSingleQuote": false,
  "endOfLine": "lf"
}

最后更新:2025年

这是我的个人文档