# 一、安装

# 安装命令

//npm
npm install --save-dev --save-exact prettier
//yarn
yarn add --dev --exact prettier

# 二、文件准备

# 创建 prettier 所需文件

在根目录下创建 .prettierrc.js 配置文件及 .prettierignore 忽略文件

# 三、创建配置

# 1. 创建格式化参考规则

.prettierrc.js 中写入以下内容:

// 此处的规则供参考,其中多半其实都是默认值,可以根据个人习惯改写
module.exports = {
  printWidth: 80, // 单行长度
  tabWidth: 2, // 缩进长度
  useTabs: false, // 使用空格代替 tab 缩进
  semi: true, // 句末使用分号
  singleQuote: true, // 使用单引号
  quoteProps: 'as-needed', // 仅在必需时为对象的 key 添加引号
  jsxSingleQuote: true, //jsx 中使用单引号
  trailingComma: 'all', // 多行时尽可能打印尾随逗号
  bracketSpacing: true, // 在对象前后添加空格 - eg: {foo: bar}
  jsxBracketSameLine: true, // 多属性 html 标签的‘>’折行放置
  arrowParens: 'always', // 单参数箭头函数参数周围使用圆括号 - eg: (x) => x
  requirePragma: false, // 无需顶部注释即可格式化
  insertPragma: false, // 在已被 preitter 格式化的文件顶部加上标注
  proseWrap: 'preserve', // 不知道怎么翻译
  htmlWhitespaceSensitivity: 'ignore', // 对 HTML 全局空白不敏感
  vueIndentScriptAndStyle: false, // 不对 vue 中的 script 及 style 标签缩进
  endOfLine: 'lf', // 结束行形式
  embeddedLanguageFormatting: 'auto', // 对引用代码进行格式化
};

格式化规则还可以写在如下文件中 (按优先级由高至低排列):

1. 项目的 package.json 文件中

2. .prettierrc.json.prettierrc.yml 文件中

// 格式示例
{
  "trailingComma": "es5",
  "tabWidth": 4,
  "semi": false,
  "singleQuote": true
}

3. .prettierrc.jsprettier.config.cjs 文件中

// 格式示例
module.exports = {
  trailingComma: 'es5',
  tabWidth: 4,
  semi: false,
  singleQuote: true,
};

除此之外还可以写在很多类型中,详见 preitter 官网,此处不赘述。

# 2. 配置忽略文件

.prettierignore 中写入以下内容:

# Ignore artifacts:
build
coverage
# Ignore all HTML files:
*.html

# 四、格式化文档

# 1. 命令行格式化

# (1)格式化全部文档

npx prettier --write .
//或
yarn prettier --write .

# (2)格式化指定文档

npx prettier --write src/components/Button.js
//或
yarn prettier --write src/components/Button.js

# (3)检查文档是否已格式化

npx prettier --check .
//或
yarn prettier --check .
//检查指定文件同上

# 2. 利用编辑器插件进行格式化

在编辑器中搜索相应的 Prettier 安装,即可运用编辑器快捷键进行格式化。

常见的编辑器对应插件名
VS CodePrettier - Code formatter
Emacsprettier-emacs
Vimvim-prettier
Sublime TextJsPrettier
Atomprettier-atom

重要提示:编辑器中的 Prettier 格式化规则也可在设置中编写,但实际执行时会以本地规则为优先。

# 3. 集成在 ESlint 中

ESlint 与 Prettier 可能会冲突,故需做如下设置:

//1. 安装 eslint-config-prettier 插件
npm i -D eslint-config-prettier
//2. 在 eslint 的配置文件中写入以下内容
 extends: ['plugin:prettier/recommended'], // 避免与 prettier 冲突

# 4. 集成在 git 生命周期中

搭配 lint-staged 与 husky 完成

----- 正文完 -----

----- 如下为内容以上规则(三 - 1)对应的美化效果,供参考

美化前:

function HelloWorld({greeting = "hello", greeted = '"World"', silent = false, onMouseOver,}) {
  
  
  let quotePropsDemo = {
    a:1,
    'b-2':2,
    'c':3
  }
  let arrowParensDemo =x=>x
  
  if(!greeting){return null};
     // TODO: Don't use random in render
  let num = Math.floor (Math.random() * 1E+7).toString().replace(/\.\d+/ig, "")
  return <div className='HelloWorld' title={`You are visitor number ${ num }`} onMouseOver={onMouseOver}>
    <strong>{ greeting.slice( 0, 1 ).toUpperCase() + greeting.slice(1).toLowerCase() }</strong>
    {greeting.endsWith(",") ? " " : <span style=<!--swig0-->>", "</span> }
    <em>
	{ greeted }
	</em>
    { (silent)
      ? "."
      : "!"}
    </div>;
}

美化后:

function HelloWorld({
  greeting = 'hello',
  greeted = '"World"',
  silent = false,
  onMouseOver,
}) {
  let quotePropsDemo = {
    a: 1,
    'b-2': 2,
    c: 3,
  };
  let arrowParensDemo = (x) => x;
  if (!greeting) {
    return null;
  }
  // TODO: Don't use random in render
  let num = Math.floor(Math.random() * 1e7)
    .toString()
    .replace(/\.\d+/gi, '');
  return (
    <div
      className="HelloWorld"
      title={`You are visitor number ${num}`}
      onMouseOver={onMouseOver}
    >
      <strong>
        {greeting.slice(0, 1).toUpperCase() + greeting.slice(1).toLowerCase()}
      </strong>
      {greeting.endsWith(',') ? (
        ' '
      ) : (
        <span style=<!--swig1-->>", "</span>
      )}
      <em>{greeted}</em>
      {silent ? '.' : '!'}
    </div>
  );
}

# 五、常见配置项

/**
 * @see https://prettier.io/docs/en/options.html#print-width
 * @author lcm
 */
module.exports = {
  /**
   * 换行宽度,当代码宽度达到多少时换行
   * @default 80
   * @type {number}
   */
  printWidth: 80,
  /**
   * 缩进的空格数量
   * @default 2
   * @type {number}
   */
  tabWidth: 2,
  /**
   * 是否使用制表符代替空格
   * @default false
   * @type {boolean}
   */
  useTabs: false,
  /**
   * 是否在代码块结尾加上分号
   * @default true
   * @type {boolean}
   */
  semi: false,
  /**
   * 是否使用单引号替代双引号
   * @default false
   * @type {boolean}
   */
  singleQuote: true,
  /**
   * 对象属性的引号处理
   * @default "as-needed"
   * @type {"as-needed"|"consistent"|"preserve"}
   */
  quoteProps: 'as-needed',
  /**
   * jsx 中是否使用单引号替代双引号
   * @default false
   * @type {boolean}
   */
  jsxSingleQuote: true,
  /**
   * 在 jsx 中使用是否单引号代替双引号
   * @default false
   * @type {boolean}
   */
  /**
   * 末尾是否加上逗号
   * @default "es5"
   * @type {"es5"|"none"|"all"}
   */
  trailingComma: 'none',
  /**
   * 在对象,数组括号与文字之间加空格 "{foo: bar}"
   * @default true
   * @type {boolean}
   */
  bracketSpacing: true,
  /**
   * 把多行 HTML (HTML, JSX, Vue, Angular) 元素的 > 放在最后一行的末尾,而不是单独放在下一行 (不适用于自关闭元素)。
   * @default false
   * @type {boolean}
   */
  bracketSameLine: false,
  /**
   * 当箭头函数只有一个参数是否加括号
   * @default "always"
   * @type {"always"|"avoid"}
   */
  arrowParens: 'always',
  /**
   * 为 HTML、Vue、Angular 和 Handlebars 指定全局空格敏感性
   * @default "css"
   * @type {"css"|"strict"|"ignore"}
   */
  htmlWhitespaceSensitivity: 'ignore',
  /**
   * 是否缩进 Vue 文件中的 & lt;script > 和 & lt;style > 标记内的代码。有些人 (比如 Vue 的创建者) 不使用缩进来保存缩进级别,但这可能会破坏编辑器中的代码折叠。
   * @default "always"
   * @type {"always"|"avoid"}
   */
  vueIndentScriptAndStyle: false,
  /**
   * 文件结束符
   * @default "lf"
   * @type {"lf"|"crlf"|"cr"|"auto"}
   */
  endOfLine: 'crlf',
  /**
   * 因为使用了一些折行敏感型的渲染器(如 GitHub comment)而按照 markdown 文本样式进行折行
   */
  proseWrap: 'never',
  // 是否使用根目录下的 EditorConfig 配置文件
  useEditorConfig: false,
  /**
   * HTML\VUE\JSX 每行只有单个属性
   * @default true
   * @type {boolean}
   */
  singleAttributePerLine: true,
  disableLanguages: ['html']
}