TypeScriptのコンパイル(トランスパイル)が爆裂に遅いことの対策を考える

Raspberry Pi上でTypescriptのコンパイルをやってみようと思い、tscを実行してみたところ、コマンドラインにもどって来ません。あれ、コンパイラが壊れているのかなと思っていたら、その後で戻ってきます。単に時間がかかっていただけのようです。tscには計測機能がついているのでコンパイル時間を計ってみるとこの通り。

pi@raspberrypi:~/ts $ tsc --diagnostics st.tsFiles:               2Lines:           17319Nodes:           77389Identifiers:     29814Symbols:         44284Types:            4340Memory used:    32591KI/O read:        0.02sI/O write:       0.00sParse time:      2.20sBind time:       1.37sCheck time:      6.05sEmit time:       0.23sTotal time:      9.86s

なにか凄いコードをコンパイルしたとか言うわけでは無く、公式のこの5行のコードを食わせただけです。

function greeter(person: string) {    return ""Hello, "" + person;}var user = ""Jane User"";document.body.innerHTML = greeter(user);

どうもlib.d.tsというTypeScriptのライブラリのパースとチェックに時間がかかっている模様。tsc is slow to process lib.d.ts · Issue #3298 · Microsoft/TypeScript · GitHubたしかに先の結果でも対象行が凄い量になっています。ライブラリをくっつけずにコンパイルするとこの通り大分と早くなります。

pi@raspberrypi:~/ts $ tsc --nolib --diagnostics st.tserror 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:               1Lines:              10Nodes:              32Identifiers:         9Symbols:             7Types:              15Memory used:     9694KI/O read:        0.00sI/O write:       0.00sParse time:      0.12sBind time:       0.04sCheck time:      0.14sEmit time:       0.23sTotal time:      0.53s

ただライブラリを付けないと意味が無いので、ライブラリ部分のチェックだけ外してみると最初よりは大分と早くなっています。ただ開発していてストレスがかかるレベルですね。rpi2でこれなのでrpi1とかだとどうなるんだろう。

pi@raspberrypi:~/ts $ tsc --skipDefaultLibCheck --diagnostics st.tsFiles:               2Lines:           17319Nodes:           77389Identifiers:     29814Symbols:         44111Types:              36Memory used:    21564KI/O read:        0.02sI/O write:       0.00sParse time:      2.19sBind time:       1.34sCheck time:      0.17sEmit time:       0.23sTotal time:      3.94s

で、これではお話にならないので対策を考えることにします。rpi2に入れたnodeで動かしたいので最初からちゃんとリモートで動く環境を作りたいんです。そもそもライブラリをチェックしたりコンパイルする必要も無いのだから、プリコンパイルしてリンクの時だけくっつけたらいいのでは無いかと思い検索したら同じ事を考えている人がいました。How to use compiler API to hold lib.d.ts in precompiled form · Issue #2030 · Microsoft/TypeScript · GitHubが、この方法だとソースの中身をいじる必要がありそうなのでパス。自分はそもそも今からTypeScriptを覚えようとしている段階なので、覚える前にソースをいじらないといけないというのでは順序が逆なので。次に考えたのが、atom-typescriptにはtsの保存と同時にjsを生成する機能があるので、それを使えばいいというソリューション。自分はRemote-FTPパッケージを使っているので、もともとリモートファイルをローカルファイルの様に編集できているので、リモートのtsを編集して保存すると同時にjsができれば簡単です。が、Remote-FTPがリモートのファイルを更新してくれるのは、エディタ画面上で保存ボタンを押したときのみで、atom-typescriptが自動生成するファイルをリモートに保存してくれる訳ではありませんでした。この延長線上で考えたのがRemote-FTPにはローカルとリモートを同期させる機能があるので、これを使うという手。しかしファイルを更新する都度syncを実行するのは面倒です。それをやっている間に3.94秒経ちそう。でもって次に考えたのがローカルのファイル変更を検出して自動的にリモートにアップロードするという方法。調べてみるとOSXならOS標準の機能だけで実行できそうです。OSXのLaunchAgentでホストOSのファイル監視してリモートサーバーにrsyncして同期する方法 – Qiitaが、設定ファイルを見て気が重くなったのと、ファイル変更を検知するプロセスが常駐するというのはマシンの負荷が増えそうなのが気になります。この設定をした直後はいいんですが、開発が終わったらこの設定をしたことを忘れてしまって、OSを再インストールするまで常駐しそう。で、結局採用したのが、リモートのフォルダをそのままマウントする方法。一番ありきたりな手段に落ち着きました。SSHFS (SSH Filesystem) – Raspberry Pi Documentation使い方はなんてことはなくてこの通り実行するだけ。最初リモートでsshfsというサーバーが稼働するのかと思い、piの方でapt-getを実行してしまいました。これはクライアントサイドでsshをラップしてリモートをマウントしているように見せるためのものですね。マウントするとローカルのマウントポイントの名前とアイコンが変わりました。マウントしてローカルのatomでtsファイルを更新したら(5行目のgreeterを康雄にしました)、リモートのjsが更新されています。マルチバイト文字でも問題なし。とりあえずこれでTypeScriptの学習を進めます。”””

コメントをどうぞ

メールアドレスが公開されることはありません。 が付いている欄は必須項目です