stylelint(css, scss対応のLinter)を試してみた

## stylelintとは
cssやscssなどの記述エラーを検出してくれるLinterです。
Lint機能に加え、自動でコードフォーマットを整える機能も備わっています。
https://stylelint.io/

本記事では、stylelintをローカルインストールし、実験的に動かすまでを紹介します。

### stylelint導入のメリット

- css、scssコーディング時の構文エラー防止
- コーディングスタイルを遵守し、コードの一貫性を保てる
- レビュアーの負担軽減

### csscombとの比較
その他のコードフォーマッターとしてcsscombという選択肢もありましたが、設定できるルールを比較したところ、stylelintよりも少ないという結果でした。また、csscombの最終コミットが2019年6月24日で開発が止まっており、現在も更新が続いているstylelintの方が今後の拡張性が見込めるため、stylelintを試してみることにしました。

- stylelintの方が設定できるルール数が多い
- 更新が継続しており拡張性が見込める


| プラグイン | 設定できるルール数 | 参考URL |
|:-----------|------------:|:------------:|
| stylelint   | 208        | https://github.com/stylelint/stylelint/blob/master/docs/user-guide/rules/list.md         |
| csscomb       |26        | https://github.com/csscomb/csscomb.js/blob/dev/doc/options.md       |
※Visual Studio Marketplaceのcsscombのページにおいても、stylelintを使う選択肢が提示されています。
https://marketplace.visualstudio.com/items?itemName=mrmlnc.vscode-csscomb


## 導入手順

## 前提
stylelintを使用するにあたって、Node.js v13.12.0以降のバージョンがインストール済みである必要があります。

```sh
$ node -v
v15.10.0

$ npm -v
7.5.3
```

## 1.stylelintのインストール
公式の手順に従って実行していきます。

https://stylelint.io/user-guide/get-started

以下のコマンドでローカルにインストールします。

```shell
$ npm install --save-dev stylelint stylelint-config-standard
```

package.jsonに以下の記述が追加されます。

```package.json
{
  "devDependencies": {
    "stylelint": "^13.12.0",
    "stylelint-config-standard": "^21.0.0"
  }
}
```

### エラーが出た場合

```shell

npm WARN read-shrinkwrap This version of npm is compatible with lockfileVersion@1, but package-lock.json was generated for lockfileVersion@2. I'll try to do my best with it!
npm ERR! code EACCES
npm ERR! syscall mkdir
npm ERR! path /Users/ユーザー名/.npm/_cacache/index-v5/c4/3b
npm ERR! errno -13
npm ERR!
npm ERR! Your cache folder contains root-owned files, due to a bug in
npm ERR! previous versions of npm which has since been addressed.
npm ERR!
npm ERR! To permanently fix this problem, please run:
npm ERR!   sudo chown -R 501:20 "/Users/ユーザー名/.npm"

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/ユーザー名/.npm/_logs/2021-03-25T09_00_20_370Z-debug.log
```

npmのバージョンが古いとエラーが出力されます。
対処として、エラーメッセージ内にコマンドがあるので実行します。

```shell
$ sudo chown -R 501:20 "/Users/ユーザー名/.npm"
```
再度インストールコマンドを実行してみてください。

## 2.構成ファイルの作成
プロジェクト配下に移動して、構成ファイルを作成します。
これでLint実行時にデフォルトのルールが適用されます。

```sh
$ echo "{
  \"extends\": \"stylelint-config-standard\"
}" > .stylelintrc.json
```

## 3.package.jsonへ追加
npm install --save-dev でインストールした場合は、コマンドをそのまま実行できません。
package.jsonのscriptにコマンドを追記することで、はじめて実行可能となります。

```package.json
{
  "scripts": {
    "lint:stylesheet":"stylelint --fix **/*.css"
  }
}
```

## 4.stylelintで整形してみる

こちらが元ファイルです。

```test.css
/*Cが大文字*/
@Charset "utf-8";

/*謎の行間とコロンの前後にスペース*/
#p {

  font-size   :   large;

}

/*セミコロンがいっぱい*/
#p {
  color:#f00;;;;
}

/*値なし*/
#p { color:}

```

npxでstylelintを実行してみます。
引数に--fixをわたすことで、ルールから外れたコーディングをstylelintが自動で修正してくれます。

```sh
$ npx stylelint --fix test.css
```

以下が実行結果です。プロパティの値が指定されていない場合消してくれると良かったのですが、Linterはそこまではしてくれないようです。値を指定しないというのは相当レアケースで、その他のスタイルに影響を及ぼすわけでもないので、そのままでも問題無いと思います。

```sylelint実行後のtest.css
/*Cを小文字へ自動変換*/
@charset "utf-8";

/*余計なスペースが削除*/
#p {
  font-size: large;
}

/*余計なセミコロンが削除*/
#p {
  color: #f00;
}

/*値なしはそのまま*/
#p { color: ; }

```

コンソールには2重定義のエラーが出力されていました。2重定義の場合はどちらが正しいのかstylelintは自動判別できないので、エラーメッセージを見て直していくしかなさそうです。

```
  9:1  ✖  Unexpected duplicate selector "#p", first used at line 3   no-duplicate-selectors
 13:1  ✖  Unexpected duplicate selector "#p", first used at line 3   no-duplicate-selectors
```

### さいごに
今回は、npxコマンドで試験的にデフォルトルールでstylelintを動かしてcssに対してのフォーマット動作を確認してみました。デフォルトで利用しても最低限のフォーマットが効きましたが、stylelintでは設定可能なルールが多いので、これから本格導入に向けて更に調べていきたいです。

次回はVSCodeでの利用を想定して、sytlelint拡張機能の導入と設定手順をまとめたいと思います。