Visual Studio Code で TypeScript でExpress

# やること

## Expressの開発をVisual Studio Codeで行う環境を作ります

visual studio code のサイトに TypeScriptでExpressのサンプルがあるのですが、ちょっと気になるところがあるので、そのへんを直しつつ、開発環境を作りたいと思います。

# ダウンロード

元ネタは[ここ](https://github.com/Microsoft/vscode-samples/tree/master/node-express-typescript)にあります。感謝しつつ使わせて頂いております。

# 直したいところ

個人的には次の箇所が気になりました。

- `gulp`をグローバルにインストールして使う感じになっている。
    - ローカルにインストールして、他のプロジェクトとバージョンの競合とかを気にしなくてもよいような環境にしたい。
- `src`の中に`*.ts`と`*.less`のコンパイル結果を出力している。
    - 出力結果をまとめるディレクトリを用意してそこに出力したい。
- `tests`についても同様に、コーディング対象なのかコンパイルして出力したファイルなのかを分けて管理したいところ。

# gulpの件

Visual Studio Codeはgulpのタスクをエディタ上から[実行できる](https://code.visualstudio.com/Docs/editor/tasks)ので便利なのですが、gulpのタスクを実行する場合は、gulpがグローバルにインストールされている必要がありそうです。

個人的には、パッケージはすべてローカルで運用したい派なので、最終的には npm 経由で動作するようにしたいと思います。

## まずgulpタスクを整理します

gulpfile.jsを見ると何個かタスクがありますが、基本的には、次の二つの流れに集約しそうです。

- `browser-sync`タスクとその依存タスク
    - ソースファイルを監視してコンパイルする処理と、コンパイル結果を監視してブラウザのリロードを行う流れ
- `test`タスク
    - テスト実行

ところで、testファイルのコンパイルは`browser-sync`の流れからのビルドになっており、`test`タスクは依存がありません。
それよりも、テスト実行時にテストコードをコンパイルする方が使いやすいような気がするので、そこを修正したいと思います。

- 修正箇所
    - gulpfile.js
        - watch タスク
            - `tests/**/*.ts` を監視して `buildTests`を実行する部分を削除します
        - test タスク
            - 依存タスクに `buildTests` を指定します

## npm 経由で実行

`package.json`の`script`に追記して ` npm run xxx` の型で実行できるようにしたいのですが、その前にコンパイル結果等の出力ファイルを別ディレクトリに分ける作業を先にやった方が良さそうです。

# 出力先を`dist`として作成

アプリケーションの出力は`dist/app`へ、テストコードのコンパイル結果は`dist/tests`へ格納することにします。
と同時に、アプリケーションのソースコードとテストコードの相対の位置関係が同じになった方が、テストコードから`require`するのに紛らわしくないので、ソースコードの方の位置も修正してしまいます。ソースコードの方は上記`dist`を`src`に変えたパスにしたいと思います。

```text
- dist
    - app
    - tests
- src
    - app
    - tests
```

## src と tests の位置を変更します

お好きな方法でファイルを移動してください。
`tsd.d.ts`ファイルに記載されているバスの位置がずれていると思いますので、そこ修正が必要です。

## gulpfile.jsを修正します。

### パスを修正
全てのタスクのパスを修正する必要があります。
個人的な好みでは、定数定義をしておいてそれを利用する感じにしたいです。

### コンパイルしないファイルを処理
`less`と`typescript`はコンパイルして`dist/app`へ出力しましたが、それ以外のファイル（ここではsrc/app/view/*.jade)を`dist`に移動しないといけませんので、そのタスクを下記のような雰囲気で作成します。

```js:gulpfile.js
gulp.task('views', function (cb) {
  return gulp.src([
    path.join(conf.path.src.app, 'views/**/*.jade')
  ]).pipe(gulp.dest(path.join(conf.path.dist.app, 'views'));
});
```

watchに監視も追加してください。また、`buildAll`の依存タスクにも追加します。

```js
  gulp.watch(path.join(conf.path.src.app, 'views/**/*.jade'), ['views']);
```

```js
gulp.task('buildAll', ['build', 'buildTests', 'less', 'views']);
```

# npm 経由での実行

`package.json`を見ると、scriptのところは下記のようになっています。

```json:package.json (抜粋)
  "script": {
    "start": "node ./src/www.js",
    "test": "mocha ./tests/test.js"
  },
```

とりあえず、既存部分について、下記のようにします。

- `start` パスを直す。また、起動前にビルドするようにしたい。
- `test` mochaを直接実行していますが、先ほどgulpタスクでビルドしてからテスト実行するようにしましたので、それを呼び出すように。

また、ほかのgulpタスクも実行できるように下記を追加したいと思います。
- `start-dev` 開発用に起動。gulpの`browser-sync`タスクを実行する。
- `build` gulpの`buildAll`を実行する。

```javascript:package.json
  "scripts": {
    "start": "gulp buildAll && node ./dist/app/www.js",
    "test": "gulp test",
    "start-dev": "gulp browser-sync",
    "build": "gulp buildAll"
  },
```

# デバグしてみる

Visual Studio Codeで Debug ができます。これは便利ですね。
このサンプルには Visual Studio Code のデバグのための設定(.vscode/launch.json)がすでにされていますが、このままではsourceMapが有効になっていないので、そのへんを修正します。

正確には[この辺の資料](https://code.visualstudio.com/docs/editor/debugging)(JavaScript Source Mapsの項)を確認する必要がありますが、ポイントは次の通りです。

- launch.json
    - program には tsファイルを指定する
        - 例： `"program": "./src/app/www.ts",`
        - （js を指定しても動いたけど、上記資料ではtsを指定すると書いてあるので、それに則ります）
    - sourceMaps はもちろん`true`にする
    - outDir に js ファイルの場所を指定する
        - 例： `"outDir": "./dist/app"`
- tsconfig.json
    - sourceMap を true にしてください
    - inlineSourceMap は好みに応じてどちらでも大丈夫です
    - outDir にluanch.jsonと同じように設定します
        - 例： `"outDir": "./dist/app"`

debugしている図
![スクリーンショット 2016-01-08 19.27.13.png](https://qiita-image-store.s3.amazonaws.com/0/83996/c1416246-b5a2-d88f-59c2-bf57d7ab2a16.png)



# まとめ

結構直してしまいました、、、
でも、ひな形として使えるといいな。

結果はここに置いておきました。
[base-typescript-express](https://github.com/t-mimura/base-express-typscript)

# 他にも気になるところ

- *.js.mapが出力されるので、開発じゃなくてリリース用のビルドではmapファイル作らないとか切り替えたい。
- jadeそのままコピーしたけど、もっといい解決方法ないかな。
- less じゃなくて　SCSS の方がいいかも。