vscode で stylelint を設定したはずが効かなくなってる問題

Ateam Finergy Inc. Advent Calendar 2021の7日目は、@ariariasria が担当します

# はじめに

みなさま。
vscode の Stylelint 効いてますか？
CSS を扱うプロダクトには、[stylelint.vscode-stylelint](https://marketplace.visualstudio.com/items?itemName=stylelint.vscode-stylelint)（以後vscode-stylelint） を
extension として利用しているケースが多いと思います。

今回 `stylelint.vscode-stylelint` を使用しているケースを踏まえて、
vscode と Styleint をメンテナンスしていきましょう。

vscode 上で Styleint が動作しているかチェックしてください。:thinking:

# 現状

- vscode
    - v1.62.3
- vscode extension
    - [stylelint.vscode-stylelint](https://marketplace.visualstudio.com/items?itemName=stylelint.vscode-stylelint)
        - v1.2.1
- Product Stylelint
    - v12.0.0
- stylelint-config-standard
    - v22.0.0

各プロダクトごとに、

- `.vscode/extensions.json`
- `.vscode/settings.json`

等があるイメージです。
この記事の設定で動作しない場合は、vscode の`グローバルの設定`を修正してみてください。


# 原因

## vscode-stylelint のアップグレード  :thermometer_face: 

まず第１の原因は、VS Code の vscode-stylelint を自動アップデートにしていたことが、
Stylelint が動かない起因です。
この vscode-stylelint は、[22 Oct 2021 に v1.0.0 にメジャーアップデート](https://github.com/stylelint/vscode-stylelint/releases/tag/v1.0.0)しています。


https://github.com/stylelint/vscode-stylelint/releases/tag/v1.0.0

この影響によって、

- Stylelint 13以前のサポート停止
- Stylelintのバンドルコピーを削除
- デフォルト言語識別子がcss、 less、postcssを持つドキュメントでのみ機能
- `stylelint.syntax` 設定オプションが削除され、代わりに `stylelint.customSyntax` が追加される

とメンテナンス必須なアップデートが行われたことがわかります。

# 対応

### vscode-stylelint に対する緊急対応  :ambulance:

お急ぎの方は下記の`stylelint.validate`の追加だけで、
問題なく vscode で Stylelint が効いてくれます。


```diff
  // .vscode/settings.json
  {
    "css.validate": false,
    "less.validate": false,
    "scss.validate": false,
+    "stylelint.validate": ["css", "scss"],  // see https://github.com/stylelint/vscode-stylelint#stylelintvalidate
    "[scss]": {
      "editor.formatOnSave": true,
      "editor.codeActionsOnSave": {
        "source.fixAll.stylelint": false
      }
  },
```

動作しますが、「ガイドラインに沿って Stylelint をアップグレードしてください」と、ワーニングが出ます。
また、リポジトリでは恒久的に使用するのはオススメできないのが見てとれます。

https://github.com/stylelint/vscode-stylelint/issues/274

SCSSなら、別 extension の [scss-lint](https://marketplace.visualstudio.com/items?itemName=adamwalzer.scss-lint) を代替して使うという手もありますが、
 Last updated 2019/12/6 なので今後もメンテナンスは期待できないです。


---

もしこの時点で CSS 等 の対象ファイルを開いても Styleint が効かず
 `View > Problems`　にエラーが表示されていなければ、
Stylelint 本体が入っていないかもしれません。

`View > Problems > stylelint`　に
 `Could not load Stylelint from node_modules | error`等記載されていれば、
`$ yarn add stylelint -D` して `vscodeを再起動`して下さい。

 `vscodeを再起動`して下さい。

大事なことなので２回書きました。

stylelint を package.json に入れただけでは動作しません。

## Stylelint をアップグレード :ambulance:

> Stylelint 13以前のサポート停止

vscode-stylelint のアップグレードで `v13系` はサポート外となってしまいました。
ここからは Stylelint v13 → v14 のアップグレードになります。
各々環境が違うと思いますので、CSS Modules や SCSS を使ったプロダクトを例にアップグレードに対応していきます。


公式の Migrating to 14.0.0 はこちら

https://github.com/stylelint/stylelint/blob/main/docs/migration-guide/to-14.md


### 各パッケージのアップデート

> デフォルト言語識別子がcss、 less、postcssを持つドキュメントでのみ機能

デフォルト拡張子以外で stylelint の設定をしている場合、
Stylelint v13 → v14 のアップグレードだけでは不十分です。
SCSS なら、適切なPostCSS構文をインストール必要があります。

Stylelint のアップグレードだけだと、`$ yarn stylelint` すると下記ワーニングが出ます
`When linting something other than CSS, you should install an appropriate syntax, e.g. "postcss-scss", and use the "customSyntax" option`

---


このPostCSS構文に対応する方法は２通りあります。

1. `PostCSS構文パッケージ`を追加し、.stylelintrc に追加
1. `PostCSS構文に対応したパッケージ` を追加し、.stylelintrc に追加

１は、現在のconfig（.stylelintrc等に設定している規約）をそのまま利用できます。
２は、config自体もアップデートする必要があります。



まずは１から


#### 1. PostCSS構文パッケージを追加し、`.stylelintrc`に追加

Stylelintを更新、[postcss-scss](https://github.com/postcss/postcss-scss)を追加

```shell
$ yarn add stylelint@14.1.0 postcss-scss -D
```

Stylelint の config を修正

```diff
  // .stylelintrc
  {
    "plugins": ["stylelint-prettier"],
    "extends": ["stylelint-config-standard", "stylelint-prettier/recommended"],
+   "customSyntax": "postcss-scss",
    "rules": {
      "prettier/prettier": true
    }
  }
```

> `stylelint.syntax` 設定オプションが削除され、代わりに `stylelint.customSyntax` が追加される

`"customSyntax"` を追加して、適切なPostCSS構文をインストールするだけで、warning の表示が消えます。
無事アップグレード完了です。

デメリットは`stylelint-config-standard`が古いままです。


#### 2. PostCSS構文に対応したパッケージを追加し、`.stylelintrc`に追加


Stylelintを更新、[stylelint-config-standard-scss](https://github.com/stylelint-scss/stylelint-config-standard-scss)追加
代わりに [stylelint-config-standard](https://github.com/stylelint/stylelint-config-standard) を削除

```shell
$ yarn add stylelint@14.1.0 stylelint-config-standard-scss -D
$ yarn remove stylelint-config-standard -D
```

Stylelint の config を修正

```diff
  // .stylelintrc
  {
    "plugins": ["stylelint-prettier"],
-    "extends": ["stylelint-config-standard", "stylelint-prettier/recommended"],
+    "extends": ["stylelint-config-standard-scss", "stylelint-prettier/recommended"],
    "rules": {
      "prettier/prettier": true
    }
}
```

メリットは`postcss-scss`を追加せず、
`stylelint-config-standard-scss`のみの追従で済みます。

しかし2 を選択した場合は、注意が必要です。

`stylelint-config-standard-scss` は、
最新の `stylelint-config-standard`から拡張した config となっています。



お使いのconfigのバージョンによっては、
[`@extend`は placeholder である必要だったり、ケバブケースで命名が必要だったりと、](https://github.com/stylelint-scss/stylelint-config-standard-scss/blob/main/index.js)
以前より多くのエラーが出ている可能性があります。

さらに node-sass（LibSass）で`@import`を利用していると、記述によっては sass（Dart Sass）に移行する必要があるかもしれません。*1

とはいえ、手間はかかるかもしれませんが [LibSass is Deprecated](https://sass-lang.com/blog/libsass-is-deprecated) なのでアップデートする流れは必須かなと個人的には思います。
ちなみに [グローバル機能のサポートが切れるまで1年切ってます](https://sass-lang.com/blog/the-module-system-is-launched#future-plans)。


<br />
*1 SCSS でグローバル機能を利用していて stylelint-config-standard-scss が拡張している [stylelint-config-recommended-scss](https://github.com/stylelint-scss/stylelint-config-recommended-scss/blob/master/index.js#L27) の `'scss/no-global-function-names`を`null`にしない場合 等

# おわりに

どのような理由でパッケージや設定を変えるのかは、
難しいようで一つひとつ理解すると単純で、
メンテナンスの大事さがわかります。

また、各会社や事業により規約が定まっていると思いますが、
コードはもとより規約も腐ることが理解できました。

同じ規約で依頼したりしていると、
いつのまに化石の様な環境が出来上がっているかもしれませんね。

この記事をきっかけに、メンテナンスへの重い腰を上げるきっかけになれば幸いです。