かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

ESLint + Prettier で JavaScript と CSS を自動フォーマットするぞ

自動整形してるののメモ

ESLint

install
$ yarn add -D eslint

eslint: ^7.1.0

generate config file

対話式で設定ファイル .eslintrc.js を作成できる

$ yarn eslint --init
? How would you like to use ESLint?
❯ To check syntax and find problems 
? What type of modules does your project use?
❯ JavaScript modules (import/export)
# プロジェクトに合わせて選択
? Which framework does your project use?
  React 
  Vue.js 
❯ None of these
? Does your project use TypeScript? (y/N)
? Where does your code run? (Press <space> to select, <a> to toggle all, <i> to invert selection)
❯◉ Browser
? What format do you want your config file to be in? (Use arrow keys)
❯ JavaScript 

eslint:recommended が設定されたファイルが作成される。
( npm だと npm run eslint --init だえエラーになってしまい $(npm bin)/eslint --init なので yarn の方が楽かも。)

eslint を実行する script を作成

package.json

"scripts": {
  "lint": "eslint './src/**/*.{js,ts,jsx,tsx}'",
  "lint:fix": "eslint --fix './src/**/*.{js,ts,jsx,tsx}'"
}

.eslintrc.js の設定

.eslintrc.js

module.exports = {
    "env": {
        "browser": true,
        "es6": true,
        "node": true, // require を使う時は追加
    },
    "extends": [
      // extends は後から追加した方のルールが優先される
      "eslint:recommended",
    ],
    "globals": {
        "Atomics": "readonly",
        "SharedArrayBuffer": "readonly"
    },
    "parserOptions": {
        "ecmaVersion": 11,
        "sourceType": "module"
    },
    "rules": {
      // プロジェクトに合わせたルールを設定
      "no-console": ["warn", { "allow": ["warn", "error"] }],
      "semi": ["error", "always"],
    }
};

extends, plugin で厳し目のルールを設定して、rules で部分的に弱めるのが良さそう。

Prettier

install
$ yarn add -D prettier

prettier: ^2.0.5

設定ファイルの作成

Prettier は設定ファイルを自分で作成する必要がある
package.json 内に "prettier": {} で作成することも可能 cf. Configuration File · Prettier

$ touch .prettierrc

適当に設定を作成
.prettierrc

{
  "trailingComma": "es5",
  "tabWidth": 2,
  "singleQuote": true,
  "arrowParens": "always"
}
# Prettier の実行
$ yarn prettier --write './src/**/*.{js,ts,jsx,tsx}'

or npm-script を追加

package.json

"scripts": {
  "lint": "eslint './src/**/*.{js,ts,jsx,tsx}'",
  "lint:fix": "eslint --fix './src/**/*.{js,ts,jsx,tsx}'",
  "format": "prettier --write './src/**/*.{js,ts,jsx,tsx}'"
}

ESLint から Prettier を実行する

パッケージをインスール

$ yarn add -D eslint-config-prettier eslint-plugin-prettier

.eslintrc.js を編集

module.exports = {
    // 略
    "extends": [
      "eslint:recommended",
      "plugin:prettier/recommended", // 追加
    ],
    // 略
};

eslint-plugin-prettier が eslint-config-prettier を使ってよしなにしてくれる。
"plugin:prettier/recommended""eslint:recommended" より後に書くことで Prettier の設定が優先されるようになる。

これで eslint のコマンド実行で同時に Prettier が実行されるようになった。

$ yarn lint:fix
$ eslint --fix './src/**/*.{js,ts,jsx,tsx}'
✨  Done in 0.55s.

package.json の不要な npm-script を削除

"scripts": {
  "lint": "eslint './src/**/*.{js,ts,jsx,tsx}'",
  "lint:fix": "eslint --fix './src/**/*.{js,ts,jsx,tsx}'",
-  "format": "prettier --write './src/**/*.{js,ts,jsx,tsx}'"
}

CSS も Prettier で整形する

stylelint を利用する

パッケージをインストール
$ yarn add -D stylelint stylelint-config-standard stylelint-config-prettier

scss を使う場合は stylelint-scss もインストールする

設定ファイルを作成
$ touch .stylelintrc.json

.stylelintrc.json

{
  "extends": [
    "stylelint-config-standard",
    "stylelint-config-prettier" // 下に書いたほうが優先される
  ],
  "plugins": [
    "stylelint-scss" // stylelint-scss はプラグイン
  ],
  "rules": {
    // 独自のルールを指定
    "string-quotes": "single"
  }
}
Prettier 経由で stylelint を呼び出してフォーマットする

Prettier 経由で stylelint を呼び出してフォーマットするためのパッケージをインストール

prettier-stylelint と forkして作られた prettier-stylelint-formatter がメジャーっぽい。 (リポジトリの最終更新結構前なのが気になるけど…)
prettier-stylelint だと何故かうまくフォーマットできなかったので prettier-stylelint-formatter を使うことにしました。

$ yarn add -D prettier-stylelint-formatter

package.json

"scripts": {
  "lint": "eslint './src/**/*.{js,ts,jsx,tsx}'",
  "lint:fix": "eslint --fix './src/**/*.{js,ts,jsx,tsx}'",
  // 下記を追加
  "lint:css": "prettier-stylelint-formatter 'src/**/*.{css,scss}'",
  "lint:css:fix": "prettier-stylelint-formatter --quiet --write 'src/**/*.{css,scss}'"
}

実行

$ yarn lint:css:fix
$ prettier-stylelint-formatter --quiet --write 'src/**/*.{css,scss}'
✨  Done in 1.93s.

これで CSS もフォーマットできるようになりました (ง ˙˘˙ )ว ヤッタネ

JS と CSS のフォーマットを同時に実行できるようにする。

コマンドが別々だとめんどくさいので。
npm-script を同時に実行できるパッケージをインストール

$ yarn add -D npm-run-all

package.json npm-script を編集。

"scripts": {
  "format": "run-p lint:js:fix lint:css:fix",
  "lint:js": "eslint './src/**/*.{js,ts,jsx,tsx}'",
  "lint:js:fix": "eslint --fix './src/**/*.{js,ts,jsx,tsx}'",
  "lint:css": "prettier-stylelint-formatter 'src/**/*.{css,scss}'",
  "lint:css:fix": "prettier-stylelint-formatter --quiet --write 'src/**/*.{css,scss}'"
}

JS ファイルと CSS ファイルなので run-p で並行処理にしました。

$ yarn format
$ run-p lint:js:fix lint:css:fix
$ eslint --fix './src/**/*.{js,ts,jsx,tsx}'
$ prettier-stylelint-formatter --quiet --write 'src/**/*.{css,scss}'
✨  Done in 3.68s.

A W E S O M E (ˊo̴̶̷̤ ᴗ o̴̶̷̤ˋ)

おまけ git commit 時に自動フォーマットする

huskylint-staged を使えばコマンドから git commit する際に自動的に lint やフォーマットを実行できる GUIでのコミットはダメな場合があるっぽい

# install
$ yarn add -D husky lint-staged
# 設定

package.json

"scripts": {
  "format": "run-p lint:js:fix lint:css:fix",
  "lint:js": "eslint './src/**/*.{js,ts,jsx,tsx}'",
  "lint:js:fix": "eslint --fix './src/**/*.{js,ts,jsx,tsx}'",
  "lint:css": "prettier-stylelint-formatter 'src/**/*.{css,scss}'",
  "lint:css:fix": "prettier-stylelint-formatter --quiet --write 'src/**/*.{css,scss}'"
},
"husky": {
  "hooks": {
    "pre-commit": "lint-staged"
  }
},
"lint-staged": {
  "*.{js,jsx}": "npm run lint:js:fix",
  "*.{css,scss}": "npm run lint:css:fix"
},

pre-commit をトリガーに lint-staged を実行、ファイルが *.{js,jsx} なら npm run lint:js:fix*.{css,scss} なら npm run lint:css:fix をそれぞれ実行する。
コミット時に lint と フォーマットがかかるのでコミット完了に少し時間がかかるけど、フォーマット忘れがちな方は良いかも。
プレコミットでのフォーマットを入れるなら npm-run-all の設定は不要と思います。

 
おわり。
自分用メモに振り返りながら書いてたら思った以上に時間かかってしまった…


[参考]

木になる。