TypeScriptの生成するtsconfig.jsonの末尾に改行を付けた

https://github.com/Microsoft/TypeScript/pull/28772 の話です。

経緯

以前 TypeScriptを使い始めた という記事を書きましたが、使い始めるにあたって tsc --init を実行したところ、生成される tsconfig.json ファイルの末尾に改行が付いておらず、はじめて何か編集するときにエディタが気を利かせて末尾に改行を付けてしまい、意図せず diff が発生してしまう… という煩わしい問題が起きました。

調査

まず生成される tsconfig.json の末尾が実際にはどうなっているか詳しく見てみましたが、やはりファイル末尾に改行は付いていないようでした。UNIX のコマンドでやるなら、例えば cat -e tsconfig.json | tail とやると、ファイル末尾に改行があるかどうか簡単に分かります。cat に -e を付けると、改行を $ マークで表示してくれるはずだが、末尾にこれが付いていないことが確認できます。

https://gist.github.com/r7kamura/7c2148053e88902a98c17efa9de27f68

次に、あえて付けていないのかどうかを調べてみることにしました。Microsoft/TypeScript のリポジトリ内には tsconfig.json が複数個存在するので、これらを調べてみましたが、ファイル末尾に改行が付いているものと付いていないものが混在しており、付いているほうが多数派のようでした。複数の思想が混在しているか、あるいは誰もあまり気にしていないのではないかと推測しています。結論としては、「あえて付けていないとは言い難い」という感じでした。

次に、一般にこの手のファイルの末尾に改行を付けるべきかどうかという観点で考えてみることにしました。POSIX ではテキストファイルの末尾は改行で終わるものと規定されている、ということは知っていたので、tsconfig.json がテキストファイルであるかどうかと、POSIX 標準に従うべきかどうかが判断材料になりそうです。tsconfig.json がテキストファイルであるかどうかについては、プログラムだけが処理するようなファイルであれば議論の余地がありそうでしたが、tsconfig.json は人間が編集しやすいようにコメントアウトされたコードがデフォルトで含まれたりしているので、明らかにテキストファイルであると見なしても良さそうだと考えました。このプロジェクトで POSIX 標準に従うべきかどうかは、個人的には、まあ特にデメリット無くその方向に寄せられるのであれば嬉しいのでは、程度の感覚で考えています。とはいえ POSIX 標準に従うようになるメリットはあまり大きくないので、Pull Request を出すときにこれらの点は主張しないでおこうと考えました。

次に、同じ界隈の他のツールにおいて、この手のファイルには末尾に改行を付けるものなのかどうかも念のため調べておくことにしました。結果だけ言うと、どのツールで生成される JSON ファイルの末尾にもほぼ改行が付いていることが分かり、代表例として npm init の生成する package.json を挙げれば十分そうでした。

実装

コードをエントリポイントから追いかけてみたところ、tsc --init を呼び出したときに JSON ファイルに書き込むための文字列を生成している箇所は src/compiler/commandLineParser.ts の generateTSConfig という関数内にあることが分かったので、これを書き換えて、末尾に改行を継ぎ足すことにしました。tsconfig.json が生成されるかどうか確認するテストも既に用意されていたので、ここにも改行を継ぎ足し、上手く符号することも確認できました。

https://github.com/Microsoft/TypeScript/pull/28772

これらの作業を終えて最終的に出したのが上記の Pull Request です。英語がかなり拙い感じですが、前述した通り、POSIX が云々とかは言わずに、「ファイルをエディタで編集するときに面倒で、package.json とかには改行が付いている」ということを言っています…。

後日談

Pull Request を出して5日後に merge されていました。めでたい。上手くいけば次の TypeScript の minor バージョンあたりから、この変更が含まれるようになるのではないでしょうか。