Help us understand the problem. What is going on with this article?

prettier-v1.13.7チートシート

More than 1 year has passed since last update.

インストール

node -v && yarn -v
# v10.5.0
# 1.8.0

yarn add -D prettier
# └─ prettier@1.13.7

オプション

prettierにはどのようなオプションがあり、それを設定すると、どうコードが整形されるかが分からなかったので、v1.13.7現在のオプションと整形結果をざっと書いていきます。

デフォルト

{
  "printWidth": 80,
  "tabWidth": 2,
  "useTabs": false,
  "semi": true,
  "singleQuote": false,
  "trailingComma": "none",
  "bracketSpacing": true,
  "jsxBracketSameLine": false,
  "arrowParens": "avoid",
  "rangeStart": 0,
  "rangeEnd": Infinity,
  "parser": "babylon",
  "filepath": undefined,
  "requirePragma": false,
  "insertPragma": false,
  "proseWrap": "preserve"
}

上記がオプション指定無しの設定のようです。v1.13.7/docs/options

下記のプログラムを

index.js
// const code = `
describe('API',()=>{
  it('black 10x10 rect',done =>{
    let black= fs.readFileSync('test/10x10.png')
    pixel.parse(black)
    .then(images =>{
      let svg= pixelToSvg.convert(images[0])
      let $= cheerio.load(svg)

      let {width,height}= $('svg').attr()
      let colors= $('path').length
      let underFileSize= svg.length < limitFileSize

      equal(width,10)
      equal(height,10)
      equal(colors,1)
      equal(underFileSize,true)

      done()
    })
  })
})
// `

console.log(require('prettier').format(code, opts))のように実行すると、以下のように整形されます。

describe("API", () => {
  it("black 10x10 rect", done => {
    let black = fs.readFileSync("test/10x10.png");
    pixel.parse(black).then(images => {
      let svg = pixelToSvg.convert(images[0]);
      let $ = cheerio.load(svg);

      let { width, height } = $("svg").attr();
      let colors = $("path").length;
      let underFileSize = svg.length < limitFileSize;

      equal(width, 10);
      equal(height, 10);
      equal(colors, 1);
      equal(underFileSize, true);

      done();
    });
  });
});

printWidth

opts={printWidth:30}とした場合

describe("API", () => {
  it("black 10x10 rect", done => {
    let black = fs.readFileSync(
      "test/10x10.png"
    );
    pixel
      .parse(black)
      .then(images => {
        let svg = pixelToSvg.convert(
/// ...

tabWidth

opts={tabWidth:8}とした場合

describe("API", () => {
        it("black 10x10 rect", done => {
                let black = fs.readFileSync("test/10x10.png");
                pixel.parse(black).then(images => {
                        let svg = pixelToSvg.convert(images[0]);
/// ...

useTabs

opts={useTabs:true}とした場合

describe("API", () => {
    it("black 10x10 rect", done => {
        let black = fs.readFileSync("test/10x10.png");
        pixel.parse(black).then(images => {
            let svg = pixelToSvg.convert(images[0]);
///...

※ qiita上では半角スペースで表示されるようです

semi

opts={semi:false}とした場合

describe("API", () => {
  it("black 10x10 rect", done => {
    let black = fs.readFileSync("test/10x10.png")
    pixel.parse(black).then(images => {
      let svg = pixelToSvg.convert(images[0])
///...

singleQuote (Quotes)

opts={singleQuote:true}とした場合

describe('API', () => {
  it('black 10x10 rect', done => {
    let black = fs.readFileSync('test/10x10.png');
    pixel.parse(black).then(images => {
      let svg = pixelToSvg.convert(images[0]);
///...

trailingComma

opts={trailingComma:"es5",printWidth:30}とした場合

///...
        let $ = cheerio.load(
          svg
        );

        let {
          width,
          height,
        } = $("svg").attr();
///...

opts={trailingComma:"all",printWidth:30}とした場合

///...
        let $ = cheerio.load(
          svg,
        );

        let {
          width,
          height,
        } = $("svg").attr();
///...

bracketSpacing

opts={bracketSpacing:false}とした場合

///...
      let {width, height} = $("svg").attr();
///...

jsxBracketSameLine (JSX Brackets)

リンク先参照。

arrowParens (Arrow Function Parentheses)

opts={arrowParens:"always"}とした場合

describe("API", () => {
  it("black 10x10 rect", (done) => {
    let black = fs.readFileSync("test/10x10.png");
    pixel.parse(black).then((images) => {
///...

rangeStart, rangeEnd (Range)

リンク先参照。

parser

opts={parser:"markdown"}とした場合、codeはmarkdownとしてマークダウン内のjsが整形されるようです。

prettier.io/playground 参照

filepath

リンク先参照。

insertPragma

opts={insertPragma:true}とした場合

/** @format */

describe("API", () => {
///...

requirePragma

opts={requirePragma:true}とした場合

describe('API',()=>{
  it('black 10x10 rect',done =>{
    let black= fs.readFileSync('test/10x10.png')
    pixel.parse(black)
///...

code内に既に/** @format */が存在する場合のみ、整形されます

proseWrap

markdown用のオプションです。

opts={parser:"markdown",proseWrap:"never"}とした場合、平文などが一行にまとめられます。

prettier.io/playground 参照。

eslintと併用する

.eslintrc
---
parser: babel-eslint

extends:
  - plugin:prettier/recommended

rules:
  prettier/prettier:
    - error
    -
      printWidth: 80
      tabWidth: 2
      useTabs: false
      semi: true
      singleQuote: false
      trailingComma: none
      bracketSpacing: true
      jsxBracketSameLine: false
      arrowParens: avoid

prettierに加え、いくつかのモジュールが必要になります。

yarn add -D babel-eslint eslint eslint-config-prettier eslint-plugin-prettier
# ├─ babel-eslint@8.2.5
# ├─ eslint-config-prettier@2.9.0
# ├─ eslint-plugin-prettier@2.6.1
# └─ eslint@5.0.1

整形対象がeslintのエラーとして表示されるようになり、--fixでprettierの整形が行えるようになります。

npx eslint index.js
# 1:10  error  Replace `'API',()=>` with `"API",·()·=>·`                                                   prettier/prettier
# 2:6   error  Replace `'black·10x10·rect',done·=>` with `"black·10x10·rect",·done·=>·`                    prettier/prettier
# 3:14  error  Replace `=·fs.readFileSync('test/10x10.png')` with `·=·fs.readFileSync("test/10x10.png");`  prettier/prettier
# 4:23  error  Replace `⏎····.then(images·=>` with `.then(images·=>·`                                      prettier/prettier
# 6:14  error  Replace `=·pixelToSvg.convert(images[0])` with `·=·pixelToSvg.convert(images[0]);`          prettier/prettier

npx eslint index.js --fix
cat index.js
# describe("API", () => {
#   it("black 10x10 rect", done => {
#     let black = fs.readFileSync("test/10x10.png");
#     pixel.parse(black).then(images => {
# ...

eslint-config-vue + standardと併用する

eslint-config-vueと併用する場合は、下記のように追記します。

.eslintrc
# parser: babel-eslint
parserOptions:
  parser: babel-eslint
  ecmaVersion: 2017
  sourceType: module

env:
  browser: true

extends:
  - standard
  - plugin:vue/recommended
  - plugin:prettier/recommended
# ...
yarn add -D eslint-config-standard
# └─ eslint-config-standard@11.0.0

yarn add -D eslint-plugin-standard eslint-plugin-import eslint-plugin-node eslint-plugin-promise
# ├─ eslint-plugin-import@2.13.0
# ├─ eslint-plugin-node@6.0.1
# ├─ eslint-plugin-promise@3.8.0
# └─ eslint-plugin-standard@3.1.0

yarn add -D eslint-plugin-vue@next
# └─ eslint-plugin-vue@4.0.0
src/components/App.vue
<template>
  <div>
    <ul>
      <li v-for="tweet in tweets" :key="tweet.id_str">
        {{tweet.id}}{{tweet.name}}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tweets: []
    }
  }
}
</script>

<style scoped>
p{font-weight:bold}
li{font-family:monospace}
</style>
npx eslint src --ext vue --fix
<template>
  <div>
    <ul>
      <li v-for="tweet in tweets" :key="tweet.id_str">
        {{ tweet.id }}{{ tweet.name }}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tweets: []
    }
  }
}
</script>

<style scoped>
p {
  font-weight: bold;
}
li {
  font-family: monospace;
}
</style>

Atomで.vue--fixする場合、linter-eslintの設定を修正する必要があります。

eslint-config-airbnbと併用する(react用)

eslint-config-airbnbと併用する場合は、下記のように追記します。

.eslintrc
# ...
extends:
  - airbnb
  - plugin:react/recommended
  - plugin:prettier/recommended
  - prettier/react
# ...
yarn add -D eslint-config-airbnb
# eslint-config-airbnb@17.0.0" has incorrect peer dependency "eslint@^4.19.1".
# eslint-config-airbnb@17.0.0" has unmet peer dependency "eslint-plugin-import@^2.12.0".
# eslint-config-airbnb@17.0.0" has unmet peer dependency "eslint-plugin-jsx-a11y@^6.0.3".
# eslint-config-airbnb@17.0.0" has unmet peer dependency "eslint-plugin-react@^7.9.1".
# └─ eslint-config-airbnb@17.0.0

yarn add -D eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-react
# ├─ eslint-plugin-import@2.13.0
# ├─ eslint-plugin-jsx-a11y@6.0.3
# └─ eslint-plugin-react@7.10.0
main.jsx
import React from 'react'
import {render} from 'react-dom'

render(
  <h1>Hello, world!</h1>,
  document.getElementById('root')
);
npx eslint main.jsx --fix
# /Users/59naga/Downloads/REPOS/prettier-cheat/index.js
#   1:19  error  Unable to resolve path to module 'react'       import/no-unresolved
#   2:24  error  Unable to resolve path to module 'react-dom'   import/no-unresolved
#   4:32  error  'document' is not defined
main.jsx
import React from "react";
import { render } from "react-dom";

render(<h1>Hello, world!</h1>, document.getElementById("root"));
# (node:9942) [ESLINT_LEGACY_OBJECT_REST_SPREAD] DeprecationWarning: The 'parserOptions.ecmaFeatures.experimentalObjectRestSpread' option is deprecated. Use 'parserOptions.ecmaVersion' instead. (found in "node_modules/eslint-config-airbnb-base/index.js")

eslint-config-airbnb@17.0.0現在、eslint@5.0.1との互換性が保証されていませんので、eslint@4の使用を推奨します。

eslint-config-flowtypeと併用する

eslint-config-flowtypeと併用する場合は、下記のように追記します。

.eslintrc
# ...
extends:
  - airbnb
  - plugin:flowtype/recommended
  - plugin:prettier/recommended
  - prettier/react
plugins:
  - flowtype
settings:
  flowtype:
    onlyFilesWithFlowAnnotation: true
# ...
yarn add -D eslint-plugin-flowtype
# └─ eslint-plugin-flowtype@2.49.3
main.jsx
// @flow
import React from "react";
import { render } from "react-dom";

type Props = { label?: string };
type State = { count: number };

class MyComponent extends React.Component<Props, State> {
  // static defaultProps = {
  //   label: "Count"
  // };

  state = {
    count: 0
  };

  componentDidMount() {
    setInterval(() => {
      this.setState(prevState => ({
        count: prevState.count + 1
      }));
    }, 1000);
  }

  render() {
    const { count } = this.state;
    const { label } = this.props;
    return (
      <div>
        <p>
          {label} {count}
        </p>
      </div>
    );
  }
}

render(<MyComponent label="Count" />, document.getElementById("root"));
npx eslint main.jsx
# /Users/59naga/Downloads/REPOS/prettier-cheat/main.jsx
#    5:16  error  propType "label" is not required, but has no corresponding defaultProp declaration  react/require-default-props
# ...

flowの警告は、--fixを使わず手動で直すものが殆どと思います。(上記はstatic部分のコメントを戻すと警告は消えます)

必要に応じて、IDEからも警告を出したり、--fixできると使いやすいです。(自分はATOMのlinter-eslint,linter-flowを使っています)

参考記事

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした