TypeScriptの1.1でずーっと言われ続けてたコンパイル速度がだいぶ改善されましたね。個人的な感覚値としては3倍速くらいでしょうか。今日はそのコンパイル速度をもうちょい早くするにはって話です。
何が遅いのか
まぁ、結構前から既知なのですがlib.d.tsですね。こいつがデカくて重い。いまパッと見たら14958行で595kありました。
lib.d.tsは特別な指定なしにデフォルトで読み込まれます。だから読み込ませないためには指定が必要です。その読み込ませないって指定がtscコマンドのnoLib
オプションです。これtsc -help
では出てこないのですが、tsc --noLib
ってやってあげるとlib.d.tsが読み込まれないようになっています。
試しにやってみます。完全に空のファイルを用意してtscコマンドを叩いてみます。まずはnoLibオプションを付けないやつです。
$ tsc --diagnostics index.ts
Files: 2
Lines: 14171
Nodes: 66439
Identifiers: 23342
Symbols: 20832
Types: 5769
Memory used: 38220K
Parse time: 0.69s
Bind time: 0.42s
Check time: 1.11s
Emit time: 0.05s
Total time: 2.27s
あっ、ちなみにdiagnostics
オプションもヘルプでは出てこないんですが、コンパイルの内容とか時間が表示されます。上記では2.27秒かかってますね。完全に空のファイルでの結果なんで、最低限はこれだけかかるって数値です。
ただ、index.tsだけ指定して、空のファイルなのにdiagnostics
の結果では2ファイルで、14171行読み込まれて、66439ノードあって・・・・となっています。ここらへんが全部lib.d.tsの結果です。
では、noLib
オプションを付けてみます。
$ tsc --diagnostics --noLib index.ts
error TS2318: Cannot find global type 'Array'.
error TS2318: Cannot find global type 'Boolean'.
error TS2318: Cannot find global type 'Function'.
error TS2318: Cannot find global type 'IArguments'.
error TS2318: Cannot find global type 'Number'.
error TS2318: Cannot find global type 'Object'.
error TS2318: Cannot find global type 'RegExp'.
error TS2318: Cannot find global type 'String'.
Files: 1
Lines: 1
Nodes: 0
Identifiers: 0
Symbols: 0
Types: 12
Memory used: 5304K
Parse time: 0.03s
Bind time: 0.06s
Check time: 0.00s
Emit time: 0.09s
Total time: 0.18s
型定義エラーがいくつか出てるのが謎(なぜなら空のファイルで何も使ってないから)ですが、Total timeをみると約2秒アップで0.18秒になってます。lib.d.tsを読み込ませなかったら常に2秒アップってわけではないですが、まぁ、少なくとも早くはなります。
lib.d.tsの構成
さて、noLib
を付けたところエラーが出てます。これを解消せねばならないのですが、まずはlib.d.tsの構成から。
lib.d.tsって実は単一のファイルで全て書かれてるのではなくっていくつかの部分から成り立っています。そのいくつかの部分が以下。
ファイル名 | 説明 |
---|---|
lib.core.d.ts | JavaScript 組み込みなどの一番ベースとなる定義 |
lib.dom.d.ts | ブラウザのDOM系の定義 ※lib.core.d.tsを参照している |
lib.scriptHost.d.ts | WSHな定義 ※lib.core.d.tsを参照している |
lib.webworker.d.ts | WebWorker系の定義 ※lib.core.d.tsを参照している |
最新のリポジトリであれば、lib.es6.d.tsとかが入ってますね。最終的な構成がどうなるかはまだ分かりませんが。
また、将来のver2.0ではlib.d.tsを分割してモジュールかしようって話も出てます。
話を戻して、上で書いたように4種類のファイルでlib.d.tsが構成されていて、lib.core.d.tsが一番ベースになってます。じつのところ上でエラーが出ていたArrayやBooleanなどの組み込み型はここで定義されています。
lib.core.d.ts を参照する & まとめ
lib.core.d.tsを参照するためには、ベタベタな方法ですが、npmで取ってきたtypescriptのbinディレクトリ下に上記のファイルが配置されてるので、コピーします。隠しオプションとかトリプルスラッシュとかで指定できればきれいなんですが、探す限りなかったのがちょいと残念です。
で、そのコピーしてきたlib.core.d.tsを///<referenceで参照してtscを走らせた結果が以下。
$ tsc --diagnostics --noLib index.ts
Files: 2
Lines: 1122
Nodes: 1957
Identifiers: 679
Symbols: 595
Types: 148
Memory used: 7950K
Parse time: 0.20s
Bind time: 0.09s
Check time: 0.06s
Emit time: 0.04s
Total time: 0.39s
エラーが出てる状態から0.2秒ほど時間がかかったけど、lib.d.tsを素で読むのとでは1.8秒ほど早い感じでしょうか。
例えば、ブラウザ用のコードでdom操作とかjQuery経由でしかしなくって実はlib.dom.d.tsの内容ほとんど使ってへんとかやったら、上記の方法でもいいかなと思ってます。まぁ、どこまでこの約1秒の差を気にするか、lib.dom.d.tsの内容で必要なものだけ抜き出す手間よりも優先かなどなど、天秤にかけル必要がありますが、まぁ、できますよってことで。
早く、2.0のモジュール化が欲しいっす。