TypeScript + Visual Studioでnode.jsプログラミングをするための環境構築

node.js導入までの経緯

ずっとローカルで動かすバッチ処理、たとえばプロダクトのリリース処理なんかを、C#だったりJAVAだったりPHP(!)だったりで書いてて環境が安定しなかった。
そこで、まあjavascriptはどうせ今後も長く続くだろうし、忘れることもないだろうしって事で、javascriptバッチ処理するのにnode.jsを導入することにした。


node.jsは俺みたいな貧乏人の場合、herokuくらいでしか動かせないのでサーバ用途としてはいまいち。
だけどまあバッチならローカルに突っ込んでおけばいいので、どこでも使えるだろうって事で。

node.jsの開発環境選定

node.jsをやるなら、まあ無難にCoffeeScriptさんかなと思ってたんだけど、どーもCoffeeさん好きになれない。
記述簡略化に特化してる言語って往々にして難読化するなぁと思っているんだけど、CoffeeScriptも同じ印象。書いてる人気持ちいいかもしれんけど、読む方としてはなんとも。


この辺が参考になる。
http://qiita.com/katapad/items/89b2104983ee71912df6
ここであげられている例とかも、惹かれるのは存在演算子くらいで、他のトリックはほとんど好きになれなかった。
ちなみにDefferedとかのライブラリも同じ理由で好きじゃないけど、jQueryは許容範囲と、俺なりに基準はあるみたいだけどなぜそれが駄目でこれがOKなのかとかは俺もよう説明できん。


まあそういうわけで、当初予定ではCoffeeScriptをnode.js導入のタイミングで習得しようと思ったけど、調べた限りどうにも好きになれんってことで、それなりに好きなTypeScriptでやることにした。
TypeScriptは今んとこシンプルながら記述簡略化も可能で気に入っている。


あとは開発環境だけど、手元のPCがWindowsでせっかくTypeScript使うなら入力補完がほしいので、おとなしくVisual StudioのExpressを使うことに。
node.jsといえばCloud9が有名らしいけど、まだ触ってないのでパス。Cloud9でもTypeScript使えるらしいけどね。
まあVisual Studioでいいやってことで、環境選定OK終わり。

環境構築

node.js入れる
http://nodejs.org
INSTALLをクリック。


Visual Studio Express入れる
http://www.microsoft.com/ja-jp/dev/express/
Visual Studio Express 2012 for Web」をダウンロード
Webじゃない方が多分いいんだけど、他試してないんで・・。


TypeScriptのVisual Studio用アドオンを入れる
http://www.typescriptlang.org/#Download
「Download the plugin」って方。Visual Studio使わないなら、npm install -g typescriptも可。


とりあえず必要なのは三つだけ。
Visual Studio Expressはダウンロード後、無料のアクティベーションが必要なので注意。

定義ファイルとTypeScriptのlib.d.ts

TypeScriptで開発するには定義ファイルが必要。
なんだけど、その前にnode.jsと普通のJavaScriptの違いをまず意識する必要があって、たとえばnode.jsにはwindowとかdocumentとかはないので、この辺の除外からやる。


あとnode.jsはただのjavascriptエンジンというだけではなく、「ECMAScript準拠なのでwinvowは使えないけどMathとかは使える必要がある」とか、「consoleもちょっと独自要素がある」といったちょっとした方言がある。
ので、lib.d.tsを除外するtsc --nolibでのビルドってだけじゃなくて、lib.d.tsの代わりのものが必要。


ちょっと探したけど見つからなかったので作った。
この二つダウンロードしておく。上のはlib.d.tsの代わり、下のはconsole定義用。
https://github.com/tsugehara/DefinitelyTyped/raw/master/ecmascript/ecmascript-api.d.ts
https://github.com/tsugehara/DefinitelyTyped/raw/master/console/console.d.ts


それからもちろんnode.js用の定義ファイルも必要。
TypeScript公式のサンプルにもあるけどあっちはちょっと古いので、githubから新しい定義ファイルをダウンロードしておく。
https://github.com/borisyankov/DefinitelyTyped/raw/master/node/node.d.ts
※冒頭コメントにnode.jsのバージョンがあるので、手元のnode.jsと同じになっているか注意すること


とりあえず必要なのはこの三つだけ。
もっともnode.jsにモジュール入れまくって使うような人だと全然足らないので、その辺は各自なんとかすること。

Visual Studioでプロジェクト作成

続いてVisual Studio立ち上げて、新しいプロジェクトでtypescriptのプロジェクトを指定してプロジェクト作る。


でもプロジェクトテンプレートをデフォルトのまま使うと、lib.d.tsとかが使われてしまう。
ので、作るだけ作ったらVisual Studioをおもむろに閉じて、さっき作ったプロジェクトの場所にいき、.csprojファイルをテキストエディタとかで開く。


変更する設定は、lib.d.tsを読まない、ES3用jsではなくES5用ソースを出力する、モジュール種別はAMDではなくcommonJSにするって3点なので、「」と「」を探して、こんな風に書き換える。

  <PropertyGroup Condition="'$(Configuration)' == 'Debug'">
    <TypeScriptTarget>ES5</TypeScriptTarget>
    <TypeScriptIncludeComments>true</TypeScriptIncludeComments>
    <TypeScriptSourceMap>true</TypeScriptSourceMap>
    <TypeScriptIncludeDefaultLib>false</TypeScriptIncludeDefaultLib>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)' == 'Release'">
    <TypeScriptTarget>ES5</TypeScriptTarget>
    <TypeScriptIncludeComments>false</TypeScriptIncludeComments>
    <TypeScriptSourceMap>false</TypeScriptSourceMap>
    <TypeScriptIncludeDefaultLib>false</TypeScriptIncludeDefaultLib>
  </PropertyGroup>

重要なのは下記3点。

1. <TypeScriptTarget>ES3</TypeScriptTarget> => <TypeScriptTarget>ES5</TypeScriptTarget>
2. <TypeScriptIncludeDefaultLib>true</TypeScriptIncludeDefaultLib> => <TypeScriptIncludeDefaultLib>false</TypeScriptIncludeDefaultLib>
3. <TypeScriptModuleKind>AMD</TypeScriptModuleKind>を消す


ES3→ES5は必須ではないけど、せっかくのnode.jsなのでes3はやめた方がいいかなと。
ちなみにこの設定はGUIでも出来るかもしれんけど、俺はやり方知らない。


ここまで出来たらもう一回Visual Studio開いてプロジェクト開きなおして、さっきダウンロードした3つの定義ファイルをプロジェクトに加えればコーディング準備完了。


とりあえずテスト用のコーディングとして、デフォルトで作られているapp.tsを開いて、内容全部消して、たとえばこんな感じのを書く。

///<reference path="ecmascript-api.d.ts" />
///<reference path="console.d.ts" />
///<reference path="node.d.ts" />
class NodeTest {
	constructor() {
		console.time("test");
		console.log("Math.floor(100/90)=" + Math.floor(100 / 90));
		console.timeEnd("test");
	}
}

new NodeTest();

セーブすると自動的にコンパイルされる設定になってるので、書いて保存してエラーが出なければOK*1
この時点でようやくVisual Studio Expressをエディタ兼コンパイラ化する作業が完了。お疲れ様でした。

実行用の設定

ここまでだと、エディタ兼コンパイラではあるけどデバッガではなく、F5での実行とかは出来ないので*2、実行はコマンドラインからやる必要あり。


ただ実行についても一応、外部ツールってのを登録すると、多少手間は減るのでやり方。


Visual Stuidoのメニューでツール→外部ツール→追加で、以下の内容を設定。

タイトル 適当
コマンド node.jsを入れた場所のnode.exeのパス
引数 $(ItemDir)$(ItemFileName).js
終了時にウィンドウを閉じる チェックを外す

これで登録すると、以後はツールメニューから、さっき入れた「タイトル」欄の名前のメニューをクリックすれば実行できる。
クリック前に実行したいtsファイル、初期状態ならapp.tsを選択しておく必要がある点に注意。
ちなみに「出力ウィンドウを使用」をしてもいいけど、手元の環境だと日本語がバグる。


ステップ実行とかのやり方はまだ調べてないけど、外部ツール実行である以上出来ないと思われる。

その他の小ネタ

require

node.jsで多用するrequireの書き方はこう。

import path = require("path");
class NodeTest {
	constructor() {
		var p = <path>require("path");
		console.log(p.extname("index.html"));
	}
}

importを冒頭に書いてからrequireして、require時にはキャストすること。
requireだけでも動くけど、上の例だとpがanyになってしまい、コマンド補完も型チェックもきかなくなる。


2013/07/30 追記
import path = require("path"); の時点でpath変数にpathモジュールが入っているので、上の例でのvar p = require("path");は省略してもいいようです。

文字コード

Visual Studio文字コード指定が腐っているので、日本語を扱う場合Shift_JISになって困ることがあるかも。
その場合、該当のtsファイルを選択して、ファイル→名前を付けて保存、で、「上書き保存」ってボタンの右にある小さい逆三角押すと出てくる「エンコード付きで保存」ってメニューを選択し、明示的にutf-8で保存してやればOK。

その他

複数のtsファイルで一つのjsファイルを作りたいとか、tsファイルの下にくっついてるjsファイルが邪魔とか、ソースマップいらねぇとか、大抵のことはVisual Studio Expressで出来るんだけど、長くなってきたので省略。


ちなみに一応書いたけども、俺もnode.js初心者なんでなんか抜けあるかも。
ようやく環境が出来たので、俺もばりばり勉強してくとします。




2013/07/30 追記
随分時間空いたけどこの記事の内容をちょっとだけ勉強して、あえてgruntを使わずにjgame.jsのビルドスクリプトを書いてみた。
何かの参考になるかもしれないので、スクリプト部分だけアップしておく。csproj付き。
http://tsuge.sub.jp/blog/20130730/jgame.js.batch.zip

*1:もちろん明示的にビルドしてもいいが

*2:やりようがあるかもだけど、Web用プロジェクトなのでちょっと面倒