VSCode に Code Spell Checker を導入して typo と戦ってきた

この記事は、[**SmartHR Advent Calendar 2024 シリーズ2**](https://qiita.com/advent-calendar/2024/smarthr)の9日目の記事です。

2018年のAdvent Calendarで以下の記事を書きました。

https://qiita.com/diescake/items/98c5a099e85775cd917d

なんと6年前…！

そして、この記事は6年が経過した現在でも地味に読まれています。
さすがに内容が古くなっているので更新しようと思っていましたが、せっかくAdvent Calendarの時期なので、今回は別の記事として、6年ほど運用してきた所感や知見を書いてみることにしました。

## 続・なぜtypoはよくないのか？

> スペルミスは害がある。
> 普通にバグの原因になるし、バグはなくともコードを読むときに脳に負荷をかける。
> そして一部の言語（Ruby, JavaScriptあたり）は、正確に治すのは難しく、スペルミスを直したつもりが直しきれずにバグになってしまうこともある
> （以前にAndroid StudioでJavaのリファクタリングしたときはかなり正確に、しかもコメント内まで修正が入っていた。言語によっては安全に直せるケースもある）。

「[スペルミスの多いコードを持つプロジェクトにありがちなこと](https://qiita.com/katoken-0215/items/9bb763f0935fde2ee188#%E3%82%B9%E3%83%9A%E3%83%AB%E3%83%9F%E3%82%B9%E3%81%AB%E3%82%88%E3%82%8B%E5%AE%B3)」より引用

この文章は以前の記事でも引用しましたが、このあたりの認識はあまり変わっていないです。

ただ、typoがあったとしても、静的型付けの言語を採用していたり、テストの実装によって未然に検出されるため、ランタイムに影響が出るような場面はほとんど見かけませんでした。

また、バグとまではいわなくとも、ライブラリやWeb APIなど外部に露出しているインタフェースでtypoがあると、利用者はスムーズに結合できない可能性があるし、typoを修正すると破壊的変更になるので直しづらかったりと影響が大きいよなぁ…、と思う機会はありました（主に `referer` さんを思い浮かべながら書いています :relaxed: ）

## やっぱりVSCodeのCode Spell Checkerはオススメ

あれからずっとVSCodeの[Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker)を利用していますが、特に問題なく活躍してくれています。

運用のポイントとしては、やはり継続的に誤検知（意図通りであるがtypoとして指摘される）は発生するので、問題がない単語をいかに負担なくシュッと辞書登録できるかが大事です。
（自分のVSCodeのsettings.jsonを確認すると辞書リストに約900ワード登録されていました。大盛りだ）

前記事では、VSCodeのコマンドパレットから辞書登録する方法を利用していましたが、ここ数年は「クイック修正」メニューから登録しています。

1. 単語の上にカーソルを移動
1. `cmd + .`
1. `Add: “Hoge” to user setting` を選択

クイック修正メニューはこんな表示です。この方法も操作はキーボードで完結します。

<figure>
  <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38837/1d02f028-c92d-893e-884d-b831ab725421.png" alt="クイック修正メニューのキャプチャ" /><br/>
  <figcaption>図：paylaodを辞書登録しようとしている様子。やめろ！</figcaption>
</figure>

このクイック修正メニューはCode Spell Checkerの辞書登録以外の修正でも利用頻度が高く、使い慣れていることからこの方法に落ち着いています。

こんなnステップもあるような操作しゃらくせぇ！という人は、VSCodeに専用のショートカットキーを割り当てるのもオススメです。1ステップで済みます。

## ソースツリーを対象にスペルチェックをかけてみるのもよい

プロダクトコードにまだ見ぬtypoたちがどれほど存在し、ランタイムに影響を与えているtypoがないか気になったら、ソースツリー全体にスペルチェックをかけてみるとよいです。

VSCodeのCode Spell Checkerは、VSCodeで開いているファイルのみを対象にスペルチェックを行なう仕組みなので、ソースツリー全体を対象にする場合は別の仕組みが必要になります。

Code Spell Checkerは、[CSpell](https://cspell.org/)というスペルチェックツールをVSCode拡張としてラップしたものなので、CSpellに関連のライブラリを活用すると設定が流用しやすく楽です。

余談ですが、担当プロダクトのスペルチェックをしたところ自社名のtypoが3パターン検出されました。愛社精神 :wink:

```markdown
- smarhr (2 issues in 2 files)
- smarhtr (1 issue in 1 file)
- smrthr (5 issues in 3 files)
```

### ESLintを活用する

CSpellには、[@cspell/eslint-plugin](https://github.com/streetsidesoftware/cspell/tree/main/packages/cspell-eslint-plugin)というESLintのプラグインが用意されています。フロントエンドを対象にする場合、ESLintを導入済みのことが多いので比較的導入が楽です。

詳しくは公式ドキュメントを参照してもらえるとよいですが、以下のような雰囲気でCode Spell Checkerと同様の設定をESLintの設定ファイルに流し込めます。

```jsx
rules: {
  '@cspell/spellchecker': [
    'warn',
    {
      cspell: {
        language: 'en',
        ignoreRegExpList: ['[０-９Ａ-Ｚａ-ｚぁ-んァ-ヶ亜-熙纊-黑]+'], // 日本語を無視
        words: [
          'able',
          'accesskey',
          'accountid',
          ...
        ]
      }
    }
  ]
}
```

ESLintの実行と共にスペルチェックができるようになります。

### Open all拡張機能の利用

VSCodeの拡張機能である[Open all](https://marketplace.visualstudio.com/items?itemName=kikuta.open-all-vsc-ext)を活用する方法もあります。

この拡張機能は、VSCodeのエクスプローラーで選択したフォルダを起点に、配下のすべてのファイルを一括で展開できる便利なツールです。

VSCodeのCode Spell Checkerが展開しているファイルしか対象にしてくれないなら、全ファイルを展開すれば良いじゃない？という「まっすぐいって右ストレートでぶっ飛ばす」アプローチです。
追加の設定は一切不要なので、一度結果を確認したい程度であれば結構役立ちます。

<figure>
  <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38837/4e9a5037-3c14-2add-ddf2-0a620199f54d.png" alt="813ファイルを開こうとしています。続行しますか？" /><br/>
  <figcaption>図：この先は引き返せないぞ</figcaption>
</figure>

手元のMacbookで試したところ、2000ファイルくらいは問題なく動きました。
ただ、時間はかかるので、x（旧Twitter）でインプレゾンビのブロックに励むなどして時間を潰しましょう。

## CIにスペルチェックを導入するのはオススメしない

ソースツリーへのスペルチェックとくれば、次なるはCIへの導入…となりそうですが、個人的にはtoo muchに思っていてCIに組み込みたいと思う機会はありませんでした。

チームで運用しようと思うと、得られるメリットよりも、デメリットのメンテコストの方が大きく感じます。

自分の体感ですが、未然に防げるバグ、内部品質向上の効果としてはそこまで大きくない一方で、スペルチェッカーの辞書をリポジトリでメンテしようとすると常にコンフリクトの問題がつきまといます。
また、ソースコード中のBASE64エンコードされた文字列やハッシュ値など、辞書登録してもいたちごっこにしかならない文字列もあり、あまりチームのモチベーションもあがらないような気がします。

もちろん、採用技術や環境によって効果的に運用できる場合もあるかもしれませんが、逆にスペルチェッカーによってプロダクトの品質が大きく改善されるような状況であったなら、スペルチェッカーの導入以前に優先して整備すべきことがたくさんありそうな気もしています。

## まとめ

- 引き続きVSCodeのCode Spell Checkerはオススメ
- 一度プロダクトのコードに対してスペルチェッカーを流してみるのもよい
    - ランタイムに影響のあるtypoが見つかるかもしれないし、そうでなくてもクスっとするような素敵なtypoが見つかって話しのネタになる
- もしスペルチェックをCIで回そうと思ったら、メンテの負担は発生するのでメリットと天秤にかけて考えようね

## 確認環境

* Apple M1 Pro (32GB)
* macOS Sonoma
* Visual Studio Code 1.95.3
    * Code Spell Checker 4.0.21
    * Open all 0.0.2