VSCode + TypeScriptの覚書

# はじめに
初めての言語を触るときは、なるべく作業ログを残すようにすることにした。
このログはTypeScriptを使って、とあるアプリケーションの作成を行った際のものである。

なお、一般的なNode.jsのサーバサイドアプリケーションではなく、Electronを使用したクライアントアプリケーションである。
また、以下の点に注意。

* **現在まだ作業中のため更新・変更を続ける予定である（ChangeLog参照)**
* 最終目標はElectron + Node.jsで計算機（電卓）作成である。
* 環境はOSXなので、WindowsとかLinuxは対象外である。
* 正式なドキュメントではなく、噛み砕いた表現や曖昧な表現があります。


# 環境構築・インストール編
とくになし。毎度のことながらインストールなら他の方がたくさん書いているし、あえて書かなくてもわかる。一応コマンドリストだけは控えておく。

```bash
$ brew install node
```

Visual Studio Code (VSCode)はMicrosoftのサイトから適当に持ってくればよろしい。

```bash:nodeパッケージマネージャの初期化
$ npm init
```

```bash:typescript環境の設定
$ npm install -g typescript
```

typescriptは`-g`オプションを用いグローバルにインストールした。

TypeScript編でも述べるが、`tsc`というコマンドを使って.tsファイルを.jsファイルへ変換（トランスパイル）するため、PATHが通っているところへインストールしなければならない。

TypeScriptに関しては以上の環境にてほぼ完成と言って良い。必要に応じてその他のツール、またはモジュールをインストールする。

# VSCode環境設定編
## Vimプラグインの設定
キーバインドをVimと同じにできる。
これがなかったらEclipseでの開発を行っていたかもしれない。


# TypeScript編
私が想像していたのはgccでコンパイルするような感じにできると思っていたのだが、TypeScriptには独自の設定ファイルが必要となるようである。

## 設定ファイル
### tsconfig.json
Makefile、あるいはプロジェクト設定ファイルのようなもので、プロジェクト毎に１つ必要となるもの。プロジェクトディレクトリを作成後、次のコマンドでデフォルト設定を作成できる

```bash:Typescriptプロジェクトの初期化
$ mkdir <Project Name>
$ cd <Project Name>
$ tsc --init
```

コマンドを実行すると以下のようなファイルが作成される。
必要に応じて適当な値を追記しておく必要がある。

```js:tsconfig.json
{
    "compilerOptions": {
        "outDir": "./dest",　　　// 追記：出力先Dir. webpackで必要
        "module": "commonjs",
        "target": "es6",
        "noImplicitAny": true,
        "sourceMap": true,
        "jsx": "react"          // 追記：React利用のために必要
    },
    // Webpack向けの設定
    "files": [
        "./src/index.tsx"
    ]
}
```

VSCodeでの自動生成方法については不明。
tsconfig.jsonの詳細については[ここで詳しい説明がなされている](https://html5experts.jp/vvakame/17004/)。

また以下のような参考資料が見つかった

* [TypeScript 日本語ハンドブック](http://js.studio-kingdom.com/typescript/project_configuration/tsconfig_json)

## 型定義と型定義ファイル、及びその管理
### 型定義とは
TypeScriptは静的型付け言語であるから、変数や関数の引数・返り値は型情報が必要である。この話がややこしくなるのは、もっぱらTypeScriptからJavascriptのコードを参照するときである。

Javascriptは動的型付け言語であるから、TypeScript異なり型情報を持たない。よって、TypeScriptから既存のJavascriptのコードを呼ぶためには型情報の定義が必要となる。

#### 型定義ファイル
TypeScriptのコードからJavascriptのコードを参照する際に、Javascriptコード側の変数や関数の型情報を提供するのが型定義ファイルである。

### 型定義ファイルの管理
2017/04現在は@typesというnpmで管理された型定義のレポジトリ(?)があるそうだ。

Webの各所で散見されるtdsやtypings等の型定義ファイル管理ツールはインストールする必要が無いかも知れない。調査したところによると@typesの管理はGoogleとMicrosoft共同で行っているようなので、今後は@typesを利用するほうが良いと考えられる

```bash
$ npm install --save-dev @types/<モジュール名>
```

~~管理ツールとしてどうやらtypingsというのがあるらしい。~~

```bash
$ npm install typings -g
$ cd <Project Name>
$ typings init
```

## トランスパイル
TypeScirptからJavaScriptを生成することを、コンパイルではなくトランスパイルというらしい。

VSCodeでは`Command + Shift + P`でCommand Palletを呼び出し`Configure Task Runner`で`TypeScriptプロジェクトをビルド`を選択する。

するとプロジェクトディレクトリ以下に`.vscode/tasks.json`が作成される。

```js:tasks.json
{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "0.1.0",
    "command": "tsc",
    "isShellCommand": true,
    "args": ["-p", "."],
    "showOutput": "silent",
    "problemMatcher": "$tsc"
}
```

その後は、`Shift + Command + B`のショートカットでトランスパイルが出来るようになる。
ただし、以降でwebpackを利用するため、生成されたjavascriptを確認する以外ではtsxファイルを直接トランスパイルすることはないと考えられる。

### webpack
Javascriptの依存関係を解決して、一つのファイルに纏めてくれるもの。

# React編
TypescriptでReactと使う場合は@typesから型定義もインストールする必要がある。

```bash:reactのインストール
$ npm install --save react-dom react
$ npm install --save-dev @types/react-dom @types-dom
```

## React-bootstrap
流石にReactだけでは見た目のCSS何かを記述しなければならないが、そこまでの手間が惜しい場合はbootstrapを使う方法がある。
ただし、ReactのJSX記法でbootstrapを使うためにはReactのコンポーネントが必要なので、それらをインストールする必要がある。

```bash:react-bootstrapのインストール
$ npm install --save react-bootstrap
$ npm install --save-dev @types/react-bootstrap
```

React + React-bootstrapを使うと以下のような記述が可能となる。

```ts:index.tsx
import * as React from 'react'
import * as ReactDOM from 'react-dom'
import * as ReactBootstrap from 'react-bootstrap'

function Application(props: any) {
    return (
        <ReactBootstrap.Grid>
            <ReactBootstrap.Row>
                <ReactBootstrap.Col lg={2} md={2}>  
                    // Some components
                </ReactBootstrap.Col>
                <ReactBootstrap.Col lg={2} md={2}>  
                    // Some components
                </ReactBootstrap.Col>
            </ReactBootstrap.Row>
        </ReactBootstrap.Grid>
          );
}

ReactDOM.render(<Application />, document.getElementById("application"));
```

上記tsxファイルをwebpackで一つにまとめ`bundle.js`としたものを、例えば次のようにしてhtmlファイルからロードする。

```html:index.html
<!DOCTYPE html>
<html lang="jp">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta content="Sample" name="Sample" />
    <title>Sample</title>
    <link rel="stylesheet" href="../node_modules/bootstrap/dist/css/bootstrap.min.css">
    <script type="text/javascript" src="../node_modules/jquery/dist/jquery.min.js"></script>
    <script type="text/javascript" src="../node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
    <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
    <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
    <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
    <![endif]-->
</head>
<body>
    <header>
        <div class="container">
            <h1>Sample</h1>
        </div>
    </header>
    
    <section id="application">
        <!-- ここにApplicationの内容が表示される -->
    </section>

    <script type="text/javascript" src='https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-with-addons.js'></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.js"></script>
    <script type="text/javascript" src="./bundle.js"></script>
</body>

</html>
```

# Electron編
まだその域に達していない。

# ChangeLog
- 初回投稿: 2017-04-12
- ツール等修正: 2017-04-21
- React関係追記: 2017-05-27