LintとPrettier周りのメモ

真面目に各種LintとPrettierに向き合い始めたのでメモしておきます。

今回対象にしたのは以下。

  • htmllint
  • ESLint
  • Stylelint
  • Prettier

HTMLに関してはできればEJSが良かったのですが、メンテされていそうなものが見当たらなかったので生成後のHTMLを一応チェックするくらいの気持ちで。

特に嵌まったのがPrettier。ESLintやStylelintとの連携でだいぶカオスになりました。

数日格闘した感想としては以下。

  • ESLintとの連携にはeslint-config-prettiereslint-plugin-prettierを使用
    • ESLint上からPrettierを動かす
      • したがって、設定ファイルはESLintの.eslintrc.json。あと.prettierrc
      • .eslintrc.jsonの中身は
    • 特定ディレクトリ下のファイルを無視する設定については--ignore-pathが上手く効かなかったので.eslintignoreを使用
  • Stylelintとの連携にはstylelint-prettierstylelint-config-prettierを使用
    • ESLintとノリは同じで、Stylelint上からPrettierを動かす(らしい)
      • 設定ファイルは.stylelintrc.json
    • 特定ディレクトリ下のファイルを無視する設定については.stylelintrc.json中のignoreFiles。こちらは効果あり
  • 設定ファイル中のルールは当然ESLintやStylelintのルールが適用される
    • ESLintは"extends": [ "plugin:prettier/recommended" ],、Stylelintは"plugins": [ "stylelint-prettier" ],"extends": [ "stylelint-prettier/recommended" ],を追加することで、"rules": { "prettier/prettier": [true, { /* ルールのプロパティと値を列挙 */ }},の中にPrettier用のルールの記述が可能。この中身は、tabWidthprintWidthのようなPrettier専用のプロパティも記述できる

最後の事項に「たぶんそうだろう」と気付くまで、ひたすらESLintやStylelintのルールだけで頑張ろうとしたり、逆に"prettier/prettier"の外側にPrettier用のルールを記述してエラーになったりしていたので余計に沼にハマりました……。

以下、トラブルシューティング。

トラブルシューティング1: prettier-stylelint使用時にTypeError: Cannot set property 'useTabs' of nullが表示される場合の対処

prettier-stylelintを使ってprettier-stylelint --write ...として

TypeError: Cannot set property ‘useTabs’ of null

というエラーが出てしまう現象に遭遇。

上述参考リンクより、package.json

    "prettier": {}

というプロパティを追加したところ解決しました。

トラブルシューティング2: stylelint-prettier使用時にError: Subject parameter value width cannot be greater than the container width.が表示される場合の対処

prettier-stylelintでは

  • やりたかったことが上手くできなかい
  • メンテがされていなさそう(最新の0.4.2が2年前の更新)

という点から、途中でstylelint-prettierに乗り換えることにしました。

パッケージを変更したので先ほどの

package.json

    "prettier": {}

は不要だろうと思い削除したところ、

Error: Subject parameter value width cannot be greater than the container width.

というエラーが出てしまいました。そのため、package.json

    "prettier": {}

は引き続き記述しておくことにしました。

トラブルシューティング3: ESLint + Prettierで error Replace \・・・・・・` with `・・・・・・・・“のエラーが大量に出る

  39:1   error  Replace `・・・・・・` with `・・・・・・・・`
                prettier/prettier
  40:1   error  Insert `・・`

というエラーが大量に出る現象に遭遇。

.eslintrc.json

    "rules": {
        "indent": ["error", 4],
        "prettier/prettier": [
            "error",
            {
                //一行辺りの文字数
                "printWidth": 120,
                //折り返しをしない
                "proseWrap": "never",
                //インデント
                "indent": ["error", 4],
//略

.prettierrc

{
    "printWidth": 120,
    "proseWrap": "never",
    "indent": ["error", 4],
    "useTabs": false,
    "semi": true,
    "newline-per-chained-call": ["error", { "ignoreChainWithDepth": 4 }],
    "singleQuote": true
}

合計3箇所に"indent": ["error", 4],を入れたのですが効果なく……。

最終的に

        "prettier/prettier": [
            "error",
            {
                //一行辺りの文字数
                "printWidth": 120,
                //折り返しをしない
                "proseWrap": "never",
                //インデント
                "indent": ["error", 4],
                //スペース数4
                "tabWidth": 4,

tabWidthを追加したところあっけなくエラーが消え去ってくれました……。このプロパティを入れないとダメだったようです。

トラブルシューティング4: newline-per-chained-callが効かない

    "newline-per-chained-call": ["error", { "ignoreChainWithDepth": 4 }],

を指定しているのに、チェーンメソッドが改行されてしまう問題。

//before
$navbar.find('.nav-item:not(.dropdown)').find('a').on('click', function() {

//after
$navbar
    .find('.nav-item:not(.dropdown)')
    .find('a')
    .on('click', function() {

同じ問題に当たっている方は散見されるのですが、これといって解決策が今のところ見付からず。なすがまま整形されることにしました。

トラブルシューティング5: stylelint-prettierで整形時にカンマ区切りのセレクタの列挙を改行しないようにしたい

//input
h1, h2, h3 {
    //プロパティ
}

//output
h1, h2, h3 {
    //プロパティ
}

こういうことをやりたかったのですが……

改行しないようにするのはできないようです。諦めてなすがまま整形されることにしました。

//input
h1, h2, h3 {
    //プロパティ
}

//output
h1,
h2,
h3 {
    //プロパティ
}

以上、Prettierとの格闘記でした。

参考

htmllint

ESLint

Stylelint

Prettier

ESLint

Stylelint

トラブルシューティング

この記事を書いた人

アバター

アルム=バンド

フルスタックエンジニアっぽい何か。LAMPやNodeからWP、gulpを使ってejs,Scss,JSのコーディングまで一通り。たまにRasPiで遊んだり、趣味で開発したり。