ニコ生ゲーム開発にコードルールを導入しようと思ったけど、最終的には何もしなくて良いと思った

ニコ生ゲーム開発を始めようと思ったけど環境構築の段階でワタワタしてる様子を公開する記事です。

# 3行まとめ
- 広く使われてるコードルールを導入したかった
- ts-standard、airbnb-typescriptの導入が上手くいかなかった
- ある程度のルールセットはサンプルプロジェクトで定義されているのでそれに従うことにした

# 前提
- ニコ生ゲームを開発するためには基本的に、[Akashic Engine](https://akashic-games.github.io/)というゲームエンジンを使って、JavaScriptやTypeScriptでコードを書いていきます。
- 私はJavaScriptは多少分かる、TypeScriptは初めて触るという状況です。
- node.jsもESLintも概念は知っていましたがちゃんと触ったことはありませんでした。

# コードルールを導入したかった理由
TypeScriptの初心者のため、他の人が決めてくれたコードルールに従いながらTypeScriptの書き方を勉強していこうと思いました。
また複数人での開発も視野に入れていたため、書き方の統一のために何らかのコードルールが必要でした。
ここでコードルールと言っているのはESLintの[shareable-configs](https://eslint.org/docs/latest/extend/shareable-configs)のことです。

以降は「こう考えたのでこうしてみた」という話を書いていきます。

# ts-standardを採用しようとしてみた
JavaScriptのコードルールとして有名なものは以下があることが分かりました。
> - [Google JavaScript Style Guide](https://google.github.io/styleguide/jsguide.html)
> - [JavaScript Standard Style](https://standardjs.com/rules.html)
> - [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript)

[ESLintでTypeScriptのコーディング規約チェックを自動化しよう- サバイバルTypeScript](https://typescriptbook.jp/tutorials/eslint)より

この中だとJavaScript Standard Styleが良いなと思いました。なんたってStandardって言ってますしね。標準のスタイルですって。

## TypeScript用のstandard
JavaScript Standard Styleはその名の通りJavaScript用のコード規約です。
TypeScriptには[ts-standard](https://github.com/standard/ts-standard)という、TypeScript版のStandard Styleが存在します。
まずはこれを導入しようと思いました。

ESLintの設定は`.eslintrc`というファイルで行われるとのことなので、`ts-standard`をインストールした上で以下のように記載すれば良さそうじゃないかと考えていましたが、どうやらそうじゃないようです。

```javascript:.eslintrc.js ※間違っているもの
module.exports = {
  "extends": [
    "ts-standard"
  ]
}
```

そもそも誤解していたのですが、`standard`や`ts-standard`は**ESLint用の何かではなく、ESLintの代わりになるもの**でした。
`npm eslint`でチェックする代わりに、`npm ts-standard`を実行してチェックをすれば良いというもので、`.eslintrc`から設定を加えるようなものではありませんでした。

ESLintは使った方が良いんじゃないかと思ったので`ts-standard`は諦めました。

# eslint-config-airbnb-typescript
次に考えたのが[eslint-config-airbnb-typescript](https://www.npmjs.com/package/eslint-config-airbnb-typescript)の導入です。
前述の有名なコードルール3つのうちの1つですね。
これは公式リポジトリの説明から、以下のように設定することでESLintを使用したコードチェックができることが分かっています。

```javascript:.eslintrc.js
module.exports = {
  "extends": [
    "airbnb-base",
    "airbnb-typescript/base"
  ]
}
```
ということで`akashic init -t typescript`で作成したサンプルプロジェクトに対して`eslint-config-airbnb-typescript`をインストールしようとしてみたところ、以下のようにエラーが表示されインストールすることができませんでした。

```
>npm install eslint-config-airbnb-typescript --save-dev
npm error code ERESOLVE
npm error ERESOLVE unable to resolve dependency tree
npm error
npm error While resolving: typescript-game-sample@0.1.0
npm error Found: @typescript-eslint/eslint-plugin@5.62.0
npm error node_modules/@typescript-eslint/eslint-plugin
npm error   dev @typescript-eslint/eslint-plugin@"^5.38.1" from the root project
npm error
npm error Could not resolve dependency:
npm error peer @typescript-eslint/eslint-plugin@"^7.0.0" from eslint-config-airbnb-typescript@18.0.0
npm error node_modules/eslint-config-airbnb-typescript
npm error   dev eslint-config-airbnb-typescript@"*" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps
npm error to accept an incorrect (and potentially broken) dependency resolution.
```

`eslint-config-airbnb-typescript`は7.0.0以上の`@typescript-eslint/eslint-plugin`を求めているのに対し、サンプルプロジェクトにインストールされている`@typescript-eslint/eslint-plugin`のバージョンのせいで競合しているというものです。

node.js分からないなりに推測するに、サンプルプロジェクトにインストールされている`@akashic/eslint-config`との相性が良くないのかも知れないと思いました。

# サンプルプロジェクトのコードルール

https://github.com/akashic-games/eslint-config

`@akashic/eslint-config`の[index.js](https://github.com/akashic-games/eslint-config/blob/master/index.js)を見ると分かるように、Akashic側で既にルールが定義されています。
サンプルプロジェクトのルートの`.eslintrc.js`にも似た内容が書かれているので、これの内容が`.eslintrc.js`に反映される？っぽい？？ですか？？？

# Flat Config移行の問題
手作業で`package.json`のバージョンを修正したりすれば任意のshareable-configsの導入もできそうな気もしました。
色々と試行錯誤していたところ、Flat Configというのを知りました。

https://eslint.org/blog/2023/10/flat-config-rollout-plans/

ESLintでは今まで`.eslintrc`ファイルを使用して設定を行っていましたが、今後は`eslint.config.js`というファイルで設定を行うようになるとのことです。
この変更はESLintのv9でデフォルトになり、v10からは`.eslintrc`は削除されるとのことです。
そしてv10へのアップデートは2024年末から2025年初頭とされています。

つまり今頑張って`.eslintrc`の書き方を勉強したところで、来年には既に古い知識になってしまいます。
サンプルプロジェクトにインストールされるESLintもv8ですし、必ずしも最新のESLintを使わなければいけないわけではないですが、今試行錯誤しようというのは時期が悪いなと思いました。

# 最終的に
インデントがタブなのだけ気に入らないのでスペース2つになるように書き換えて、あとはAkashicの言う通りにしようと思います。

```diff_javascript:.eslintrc.js
"@typescript-eslint/indent": [
  "error",
-  "tab",
+  2,
  {
    "FunctionDeclaration": {
```

今回の試行錯誤を通して今まで触れてこなかったESLint周りの勉強になったのは良かったですが、開発の本題でないところに時間を使い過ぎるべきではないですね。
「元のままでいっか」という結論に至るまで2週間ぐらい掛かりました。