TypeScript ESLintがモノレポ環境でOOMになるのを解決
TypeScript ESLintはTypeScriptの型情報を利用して、よくあるミスを洗い出してくれるいい子ですが、そのかわり1回TypeScriptのパーサーを挟むので重い・遅い・メモリを食うという状況になります。
重すぎるので今までCI以外では切っていたんですが、Flat Config化するにあたり、せっかくなら普段のVSCode上でエラーも出したいしということでTypeScript ESLintを全体有効化したところ、設定が誤っていて今までモノレポ環境のLintでTypeScript関連のルールが動いていなかったことが判明。エラーが2つぐらいでるようになったのは良いのですが、何やったってCIがメモリエラーで死ぬ。何なら32GBある私のPCもメモリエラーが吐かれる。
下記のようなエラーですね。
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
調べたところ、ちょうど今日解決策がissueに投稿されていました。
EXPERIMENTAL_useProjectService
というプロパティを設定すればよいようです。
flat configであれば下記のようにparserOptions
を設定しましょう。
export default [
{
languageOptions: {
parserOptions: {
...,
EXPERIMENTAL_useProjectService: true,
},
},
}
]
EXPERIMENTAL_useProjectServiceは名前の通りまだexpreimentalな機能です。
TypeScript ESLintが重い理由はts.CreateProgram
を利用しているからです(多分)。
で、上記を有効にすると、こんな感じでASTを取得します。
const program = service
.getDefaultProjectForFile(scriptInfo!.fileName, true)!
.getLanguageService(/*ensureSynchronized*/ true)
.getProgram();
これがなぜ早くなるのか、正直全くわかりませんが実際にOOMが解決されるのでなにか意味があるのでしょう。
Copilot3.5では無理でしたが、Claudeで聞くといい感じに答えてくれます。全然情報が無いですね…。
私のJS Test Outlineもts.Program利用しているので、ProjectServiceの利用を検討してみようかしら。