VS Code × stylelint【VS Code × CSScombはもう辞めよう】

:::note warn
**2024/07/17追記**
stylelintのextendsをグローバルにインストールすると、グローバルに設置されているextendsとパスが通らず、stylelint.configBasedirを指定しても実現できなかったため、ローカルインストールに変更しました。
:::

VS CodeのCSS・SCSSフォーマッターをググるとたくさんのCSScombに関する記事が出てきますが、CSScombは開発終了されておりVS Code × CSScombプラグインでも使用するのを辞めるよう警告されています。

[vscode-csscomb](https://marketplace.visualstudio.com/items?itemName=mrmlnc.vscode-csscomb)

> :warning: This plugin is archived
> The main package (csscomb) has no maintainer and does not develop. In this regard, the development of the plugin does not make sense.
> 
> Alternatively you can use:
> 
> - postcss with similar plugins.
> - stylelint
> I'm ready to go back to developing the plugin if the csscomb will develops again.

> メインパッケージ（csscomb）にはメンテナーがおらず、開発も行われていません。この点では、プラグインの開発は意味がありません。
> 
> 代わりに以下を使用することもできます:
> 
> - postcss同様のプラグインを使用します。
> - stylelint

:::note alert
**VS Code × CSScombはもう辞めよう**
:::





# 代案は？
[vscode-csscomb](https://marketplace.visualstudio.com/items?itemName=mrmlnc.vscode-csscomb)で推奨されているように、stylelintを使用してCSScombで行っていたことを実現します。





# 実現したいこと
- VS Codeでstylelintを使えるようにする
- ファイル保存時にlintが動くようにする
- CSSプロパティの並び順を揃える
- 実務で使いがちな書き方へのエラーを抑制する





# stylelintのインストール
[vscode-stylelint](https://marketplace.visualstudio.com/items?itemName=stylelint.vscode-stylelint)から拡張機能をインストールします。

![vscode-stylelint](https://i.gyazo.com/0f86c91e7d718189646820217231c85c.jpg)





# 関連パッケージを~~グローバル~~ローカルにインストール
### 1.[stylelint-config-prettier-scss](https://www.npmjs.com/package/stylelint-config-prettier-scss)
> 不要なルールや Prettier と競合する可能性のあるルールをすべてオフにします。これにより、Prettier を使用するときにスタイルの選択が邪魔になることなく、お気に入りの共有可能な構成を使用できるようになります。

Prettierを併用している場合にルールがコンフリクトするのを防いでくれるパッケージ。

```
$ npm i -D stylelint-config-prettier-scss
```

### 2.[stylelint-config-recess-order](https://www.npmjs.com/package/stylelint-config-recess-order)
> Recessや Bootstrap が行った/行っているのと同じ方法で CSS プロパティを並べ替えるstylelint構成。

CSSプロパティの並び順を自動でソートしてくれるパッケージ。
CSSプロパティの並び順に関する考え方は[こちら](https://markdotto.com/2011/11/29/css-property-order/)
別途社内ルールが存在する場合も考えられますが、このルールに統一していく動きが望ましいと思います。

```
$ npm i -D stylelint-config-recess-order
```

### 3.[stylelint-config-standard-scss](https://www.npmjs.com/package/stylelint-config-standard-scss)
> stylelint-config-standard共有設定を拡張し、SCSSのルールを設定します

stylelintの標準的な設定にSCSSのルールを拡張したパッケージ。

```
$ npm i -D stylelint-config-standard-scss
```

:::note warn
~~なぜグローバルにインストールするの？~~

~~各プロジェクトごとに`npm install`する記事がよく見受けられますが、弊社の場合、過去の案件も含め複数のプロジェクトが存在し、各々に上記パッケージをインストールするのは大変です。
また、場合によっては社外リポジトリのためにもうアクセスできないなどの障害も考えられます。~~

~~**社内でstylelintを活用する環境整備ルールが整った**という条件もあり、グローバルにインストールする手法を取りました。~~
~~グローバルインストールかローカルインストールかは環境や状況に合わせて検討で良いと思います。~~

~~※`nodebrew`等でバージョン管理している場合、バージョンごとにグローバルを持つため注意が必要です。~~
:::

:::note warn
**2024/07/17追記**
stylelintのextendsをグローバルにインストールすると、グローバルに設置されているextendsとパスが通らず、stylelint.configBasedirを指定しても実現できなかったため、ローカルインストールに変更しました。
:::





# 設定ファイルを用意
stylelintのルールを一元管理したいため、ユーザディレクトリ直下に設定ファイルを設置しました。
設定ファイルは[各種形式をサポート](https://stylelint.io/user-guide/configure/)しているので、お好みの形式で記述してください。
私は`run command`形式で統一しているため、`.stylelintrc`としました。

[ドキュメント](https://stylelint.io/user-guide/rules)

```/Users/hogehoge/.stylelintrc
// コメントアウトは解説用のため除去してください
{
  "extends": [ // 使用するパッケージを追加
    "stylelint-config-standard-scss",
    "stylelint-config-recess-order",
    "stylelint-config-prettier-scss" // ※1 stylelint-config-prettier-scssは並び順に注意
  ],
  "rules": {
    "selector-id-pattern": null, // セレクタid名をkebab-case以外でも許可
    "selector-class-pattern": null, // セレクタclass名をkebab-case以外でも許可
    "keyframes-name-pattern": null, // keyframes名をkebab-case以外でも許可
    "scss/at-mixin-pattern": null, // mixin名をkebab-case以外でも許可
    "scss/at-function-pattern": null, // function名をkebab-case以外でも許可
    "scss/dollar-variable-pattern": null, // SCSS変数名をkebab-case以外でも許可
    "scss/percent-placeholder-pattern": null, // %placeholderをkebab-case以外でも許可
    "scss/at-extend-no-missing-placeholder": null, // @extendで%placeholder以外でも許可
    "number-max-precision": [3, { "severity": "warning" }], // 小数点以下3桁以上でもwarningで止める
    "alpha-value-notation": ["number", { "severity": "warning" }], // 0.3が30%となっていてもwarningで止める 
    "font-family-name-quotes": ["always-where-recommended", { "severity": "warning" }], // font-family名のルールが適合していなくてもwarningで止める
    "property-no-vendor-prefix": [true, { "ignoreProperties": ["appearance", "text-size-adjust"] }], // autoprefixerで補えるprefixを書いていた場合、エラーとなるが、ignorePropertiesは無視する
    "comment-empty-line-before": null, // コメントの前の改行はなし
    "media-feature-range-notation": "prefix", // メディア機能の範囲では、常にプレフィックス表記を使用する
    "no-descending-specificity": null // 意図的なオーバーライドセレクタの優先順位を許可
    "block-no-empty": null, // 空のセレクタを許可
    "no-empty-source": null // 空のファイルを許可
  }
}
```

:::note warn
※1
stylelint-config-prettier-scssは他の設定を上書きするため、**必ず最後に置く**ようにしてください。
:::




# VS Codeのsettings.jsonに加筆
VS Codeのsettings.jsonにも一部設定を加筆します。

```settings.json
"css.validate": false, // VS CodeのデフォルトのCSS検証を無効化
"scss.validate": false, // VS CodeのデフォルトのSCSS検証を無効化
"stylelint.validate": ["css", "scss"], // stylelintにCSSとSCSSの検証を設定
"editor.codeActionsOnSave": { // ファイル保存時にstylelintの検証やフォーマットが実行されるように設定
  "source.fixAll.stylelint": "explicit"
},
"stylelint.configFile": "/Users/hogehoge/.stylelintrc", // stylelintの設定ファイルパスを指定
```




# stylelintを再起動
`.stylelintrc`を変更してもなかなか反映されない事象が起こりました。
VS Codeのコマンドパレットからstylelint serverの再起動を行うと反映されました。

```
> Stylelint: Restart Stylelint Server
```

![stylelintを再起動](https://i.gyazo.com/d187bd04d2ea908178476c71f572e3f2.png)


---

以上でstylelintの設定は完了です。
[vscode-csscomb](https://marketplace.visualstudio.com/items?itemName=mrmlnc.vscode-csscomb)が有効になっている場合は無効化してください。
プロジェクト内のSCSSを保存すると、プロパティの並び替えが行われます。


# 参考
- [stylelint ドキュメント](https://stylelint.io/)
- [stylelintを使ってCSSプロパティのソートと整形を自動化する](https://oshin.tokyo/entry/2020-stylelint)
- [【VSCode】StylelintでCSSプロパティを自動並び替え＆整形の設定方法（2024年1月）](https://kenyo--c.com/vscode/2838/)
- [既存プロジェクトをStylelint v14にアップグレードするときに注意すべき点](https://flex-box.net/stylelint-v14/)