grunt-typescript を TypeScript 0.9 に対応

この内容は TypeScript 0.9.0 および grunt-typescript 0.2.0 をもとに記述しています。

つい先日、TypeScript の大きなアップデートであるバージョン 0.9.0 が公開されましたね。generic や enum 、Overload on Constantsなどなどいろんな新機能が入ってます。

grunt-typescript のほうも TypeScript 0.9.0 に早々に対応しています。まぁ、ちょこちょことリポジトリから最新のソースを取って手動コンパイルしてたので TypeScript がリリースされたら、そのまま grunt-typescript も公開って形だけだったのですが。

で、ちょこちょこと追いかけてた TypeScript のソースでが、0.8.3 のころから比べると劇的に変わってます。 grunt-typescript はもともとコンパイル後の tsc.js を解析して、必要な処理を抜き出して変更して作ってたのですが諦めてしまいました。今回からはコンパイル前の tsc.ts と io.ts を参考に TypeScript で記述するように変更しました。そうしたらこれがめっちゃ楽。手動コンパイルした時に同時に生成される tsc.d.ts を参照させればある程度ですが、 WebStorm でもインテリセンスが効くし、コンパイルも怒られないし、処理フローは合わせられるし、っていうかそもそもファイルIO絡みのところはほとんど変えなくてすむし。

初めからそうしとけばよかった。。。

但し、tsc の通常の動きにはない grunt-typescript 独自の動きのところは壊れないように結構神経使いました。独自の部分は以下。

js のファイル階層を維持して、別フォルダに出力できる(っていうかそうなる)

※実はこれウソでした。正しい内容は「tsc で out オプションを付けても階層維持されてた。」に書きました。

コマンドラインの tsc に out オプションにフォルダを指定した場合って、複数のフォルダ階層の ts ファイルは全部オプションで指定したフォルダにフラットで出力されます。ちょっとこれが気に食わなかったので grunt-typescript では dest オプションにフォルダが指定されていた場合は、カレントディレクトリから対象となるそれぞれの ts までのフォルダを出力フォルダに作成して、階層を維持したまま出力します。
例えば以下のような構成で ts があったとします。

src
 - core
    - a.ts
    - b.ts
 - base
    - c.ts 
build

こいつを tsc の out オプションで build フォルダに出した場合は以下のようになります。

src
 - core
    - a.ts
    - b.ts
 - base
    - c.ts 
build
 - a.js
 - b.js
 - c.js 

でも、grunt-typescript の場合は、dest オプションに build フォルダを指定した場合は以下のようにフォルダ階層は維持されます。

src
 - core
    - a.ts
    - b.ts
 - base
    - c.ts 
build
 - src
   - core
      - a.js
      - b.js
   - base
      - c.js 
ベースパスの指定

上述したようにフォルダ階層は維持されるのですが、出力フォルダに src フォルダまで作成されています。これはこれで気持ち悪いのでそれを出力しないようにするための base_path オプションがあります。こいつに "src" を指定すると、そのフォルダは出力時に飛ばすようになっています。なので以下のような感じに出力されます。

src
 - core
    - a.ts
    - b.ts
 - base
    - c.ts 
build
 - core
    - a.js
    - b.js
 - base
    - c.js 

まぁ、現状超手抜きで base_path に指定された文字列の長さを、出力するフォルダ名の前から削除してるだけなので、例えば base_path に AAA と指定しても動作するのですが、、、これは将来的には直します。

ソースマップの絶対パスでの出力

さて、そんなこんなで上記のように出力するフォルダをいじっていたら、ソースマップに指定されるパスがおかしいと指摘を受けました。そらそうです。そもそもコンパイル側が意図していないフォルダに出力するように処理を置き換えてるので。ってことで、ソースマップの出力が指定されている場合、コンパイル完了後に力技で出力されたファイルを書き換える処理が入ってます。結構豪快です。
あと、ついで指摘を貰った時に fullSourceMapPath オプションにも対応してほしいみたいな要望も含まれてたので、ついでに対応しました。 fullSourceMapPath って tsc のコマンドラインのヘルプからは見えない(experimental になっている) オプションで、ソースマップに出力される参照先のファイルのパスが絶対パスになるようにするオプションです。

型チェックの場合でもJSファイルが出力される(gruntはエラーにならない)

これは、tsc のコマンドでは普通の動きです。ただ、grunt-typescript はいままでその動きを考慮しておらず、とりあえずコンパイラがなにかエラーを返して来たら、 grunt もエラーになるように組んでいました。(というか、今まではタイプチェックのみエラーみたいな処理がどこに記述されているか読み解けなかったって落ちなのですが・・・。)
で、http://hatz48.hatenablog.com/entry/2013/06/05/140324#comment-11696248318754873269 で型チェックの場合も JS ファイルが出力されるようにしたい、してみた、って記事をあげていただいていたので、今回から勝手に(コメント欄で事後承諾は入れてます)採用させてもらいました。記事にあげていただいていた通り ignoreTypeCheck オプションに true を設定することでエラーにならずに JS ファイルを出力しているようにします。デフォルトは今までの動作を維持するために false です。

但し、

ってのを頂いているので、判定方法とかでバグがあるかも。。今度見てみよう。。


いまのところ本家の main ブランチや release-0.9.0 ブランチに動きがないのでお休み中かなって印象なので、こちらも不具合とかない限りお休みですかねぇ。でも develop ブランチはそれなりに動いてて、多分これは次バージョンの開発やと思うんやけど、またまた結構な量の変更が入ってるのでちょこちょこと確認はしないとですね。

あっ、あと何個かもらってる Issue に反応できてないや・・・。