ES6 compat tableのTypeScriptコードのビルド時間を300秒から2秒に短縮した話と、最近のCompiler APIの動きの紹介。
先日TypeScriptの文字列を簡単にコンパイルするtypescript-simpleというライブラリを書いた。
typescript-simpleを作った動機の1つは、ES6 compat tableのTypeScript用テストを高速化することだった。
元は300件以上あるテスト項目を、テストごとにNode.js v0.11のchild_process.execSyncでプロセスを立ち上げてTypeScriptコンパイラ (tsc) でチェックしていたので、全部テストするのに300秒ぐらいかかっていた。これをtypescript-simpleで全テストをワンプロセス内で実行したら超速化するはず!と思ったけど、300秒が200秒になるぐらいだった。
あれーと思ってプロファイルを取ってみると大半が基本型定義のlib.d.tsのパースに使われていた。ということは、lib.d.tsのパース結果をキャッシュすれば2回目からは高速になるはず。
いろいろいじっていると、CompilerHostより1段上のレイヤーのLanguageServiceにはビルトインでキャッシュ機構も載っていて、公式Wikiで紹介されていたインクリメンタルビルドのサンプルを参考にして実装できた。
高速化はtypescript-simple v0.2.0でnpmにリリース済み。
結果、300秒かかっていたのが2秒に短縮されたので、プルリク送って取り込んでもらった。
このlib.d.ts読み込みが遅い問題、開発時にtscを毎回実行してる人はこれと同じコストかけてることになるのでご注意を。Visual Studioとかtsc --watchとかgrunt-typescriptが素のtscより速い理由はたしかこの辺が原因だった気がする。
将来的にはlib.d.tsの分割とか考えられてるみたいだけど、多分オンデマンドで読むわけではないので根本的にはやっぱりキャッシュ機構が必要なはず。
tscもFlowtypeのflowコマンドみたいにインクリメンタルコンパイルサーバーをデフォルトで立ち上げちゃえばいいのにね。誰か実装してくれ。
困ったこと
出力されるJSの改行コードがおかしい件
ts.createLanguageServiceで作ったLanguageServiceからコードを生成すると、出力されるJSファイルの改行コードが強制的にWindowsの\r\nになる。本家でハードコードされちゃっててどうしようもないので適当に置換した。
v1.5では修正済みなのでおとなしく待つ #1653。
tsc -dで.d.tsにprivateメソッドも出力される
公開するd.tsにprivateメソッド出したくないのだけど、オプションが見当たらなかった。意味無いから消したい。なんでprivateメソッド出してるんだろ。
手で修正するとビルドで更新するのが面倒なので、ひとまず放置。
TypeScript Compiler API周辺の最近の動き
Wikiが更新されていて、以前は1ページに長文まとめて書いてあったのが、いくつかのページに分離されて充実してきた。
また、主に海外でCompiler APIの利用例の記事が出始めた。
- Investigating TypeScript compiler APIs: TypeScript Playgroundのようなものを作るサンプル
- TypeScript 1.4 AST from Node.js | Taggart Software: TypeScript AST Nodeを列挙する
- Format TypeScript with v1.4 Language Service | Taggart Software: LanguageSerivceを使ってコードフォーマッタを作るサンプル
今後はTypeScript ASTの仕様が明確になってきて、SpiderMonkey ASTやShift ASTとの相互連携、Flowtype陣営によるd.ts読み込みなど、胸アツ展開が期待される。