Runner in the High

技術のことをかくこころみ

Elmをローカルインストールしているとelm-language-serverのDiagnosticsが動かなくなるバグを修正するPRを投げた

github.com

仕事で開発しているElmアプリケーションとElmLSの相性が悪いのかDiagnosticsが動かないことが多かった。動くときもあるが、動かない時の方が多いレベル。もう諦めてWebpackでのビルド結果を見ながら作業をしていたが、非常に生産が悪かったのでこの気に調査してみることにした。

すると、以下の条件でElmLSのDiagnosticsがうまく動かなくなるバグがあることがわかった。

  • Elmをローカルインストールしている(npm install -D elm とか)
  • main関数を公開しているエントリポイントとなるモジュールに対するテストが存在している

なぜこのような挙動になっているかというと、ElmLSは内部的にDiagnosticsの生成の際elm makeelm-test makeを使い分ける挙動になっているため。

ざっくり言うと、エントリポイントとなるモジュールに対してテストが存在している場合はelm-test makeコンパイルを行い、そうでない場合にはelm makeコンパイルを行う。今回のバグの再現条件である前者の場合elm-testはElmコンパイラのバイナリを常にグローバルインストール前提で探すため、ローカルインストールだと見つけられずDiagnosticsが生成できなくなってしまう。今回の自分の修正では、Elmをローカルインストールしている場合はelm-testに対して--compilerというElmコンパイラのパスを指定させるオプションを渡すことでバグを解決した。

なぜelm makeではなくelm-test makeを使うような挙動が存在しているかについては、推測の域ではあるがelm-test makeのほうがコードベースを網羅的にコンパイルできるからではないかと想像している。Elmコンパイラ単体ではテストコードをコンパイルできない(TestパッケージやExepectパッケージを見つけられない)ため、アプリケーションのソースコードとテストコード両方を包含してDiagnosticsを生成するためにはelmとelm-testの両方を動かさなければいけないが、可能なケースであればelm-testだけを動かすことでDiagnosticsの生成時間を短縮できる。エントリポイントにテストがあるケースではそれに該当するわけだが、ローカルインストールされている状況が考慮されていなかったため、今回のバグが生まれたと考えられる。