React + TypeScript + Webpackの最小構成

※更新履歴

- webpack2-rc & TS2.1 & @types対応
- webpack2 stable & TS2.3 対応
- React16-beta & TS2.4  対応

## 問題提起

React始めたいですよね！
でも今時、型チェックのない言語とか使いたくないですよね！

TypeScriptコンパイラもjsxに対応したし、Angular2でもTypeScriptが標準っぽいし、
とりあえずこれから始めるならTypeScriptでしょう。

ということで、主にReact初学者向けに最小構成を用意してみました。
間違っている点があればご指摘いただけると嬉しいです。

## 環境

- NodeJS 8.2
- React 16.0-beta
- TypeScript 2.4
- webpack 3.4

## 構成

今回の構成は以下です。

```
$ tree .
.
├── index.html
├── package.json
├── src
│   ├── Hello.tsx
│   └── Index.tsx
├── tsconfig.json
├── webpack.config.dev.js
└── webpack.config.prod.js
```

サンプルコードはこちら。
https://github.com/uryyyyyyy/react-redux-sample/tree/helloWorld

### package.json

```json:package.json
{
  "name": "react-typescript-redux",
  "version": "1.0.0",
  "license": "MIT",
  "scripts": {
    "build": "webpack --colors --config ./webpack.config.dev.js",
    "build:prod": "webpack --config ./webpack.config.prod.js"
  },
  "devDependencies": {
    "@types/react": "15.0.39",
    "@types/react-dom": "15.5.1",
    "ts-loader": "2.3.2",
    "typescript": "2.4.2",
    "webpack": "3.4.1"
  },
  "dependencies": {
    "react": "16.0.0-beta.1",
    "react-dom": "16.0.0-beta.1"
  }
}
```

- webpack
  - JSのビルドツール。import/exportやrequire()をブラウザ用にバンドルしてくれたりする。
- ts-loader
  - webpackの中でts(tsx)ファイルをjsに変換してくれるツール
- `@types`
  - TypeScript用の型定義ファイル

`npm run build` とすれば、開発用にSourceMap付きでビルドされます。
`npm run build:prod` とすれば、プロダクション向けにminifyしてビルドされます。

### webpack.config.dev.js

```js:webpack.config.dev.js

module.exports = {
  entry: './src/Index.tsx',
  output: {
    filename: './dist/bundle.js'
  },

  devtool: 'source-map',

  resolve: {
    extensions: ['.ts', '.tsx', '.js']
  },

  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: [
          {loader: 'ts-loader'}
        ]
      }
    ]
  }
};
```

行数多くないですね。
`src/Index.tsx` を起点として、.ts, .tsx, .jsファイルをビルドしてくれます。
あとソースマップも吐いてくれます。

（webpack.config.prod.jsはここでは省略しますが、本番向けのminify設定などが入っていて、sourcemapは外してあります。）

### `@types`

型定義については、TypeScript2.0系から、npmパッケージとして型定義が提供されるようになりました。これにより、これまでのtsdやtypingsが不要になります。
バージョン管理もnpmに任せられて楽ですね。

### tsconfig.json

```json:tsconfig.json
{
  "compilerOptions": {
    "strictNullChecks": true,
    "noUnusedLocals" : true,
    "noImplicitThis": true,
    "alwaysStrict": true,
    "outDir": "./dist/",
    "sourceMap": true,
    "noImplicitAny": true,
    "lib": ["dom", "ES2017"],
    "module": "ES2015",
    "target": "es5",
    "jsx": "react"
  }
}
```

TypeScriptのコンパイルをするときに必要な設定ファイルです。
jsxを有効にするか、対象とするファイルはどれか、null Checkなどを厳密にするか、などを見てくれます。
細かいところは今回は割愛しますが、特にブラウザにおいてはES Modulesが主流なので、 `"module": "ES2015"` で動くようにしておきましょう。

長かったですが設定ファイルは以上です。

### source

```html:index.html
<!DOCTYPE html>
<html>
<head>
  <title>React minimal</title>
</head>
<body>
<div id="app"></div>
<script src="dist/bundle.js"></script>
</body>
</html>
```

```ts:src/Index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import Hello from "./Hello";

ReactDOM.render(<Hello content="hello world"/>, document.getElementById('app'));
```

ここでは、HelloというReact Componentを、idが`app`のDOMに配置するように書いています。
DOMに設置するときはReact-domを使います。（Reactはcoreと、それぞれの実行環境によってパッケージが分かれています。例えばReact-Nativeなどですね。）

```ts:src/Hello.tsx
import * as React from 'react';

export interface Props {
    content: string;
}

export default class MyComponent extends React.Component<Props, {}> {
    render() {
        return <div>{this.props.content}</div>
    }
}
```

単純な例です。
Prosが癖がありますが、上流コンポーネント（今回はIndex.tsx）から、contentフィールドにstring値が渡ってくるので、それを表示するだけの簡単なコンポーネントです。


## Buildしてみる

まずは `npm install` 
これでreactなどのパッケージと型定義ファイルがダウンロードされます。

そして、以下を入力。

```
$ npm run build
...

ts-loader: Using typescript@2.4.2 and ~~/react-redux-sample/tsconfig.json
Hash: 0cf7eff1bfee20083dba
Version: webpack 3.4.1
Time: 2541ms
               Asset    Size  Chunks                    Chunk Names
    ./dist/bundle.js  761 kB       0  [emitted]  [big]  main
./dist/bundle.js.map  906 kB       0  [emitted]         main
...
```

こんな感じになれば成功です。`dist/bundle.js` と、そのソースマップが吐かれます。
あとはindex.htmlを開くと、bundle.jsが読み込まれて、画面に「hello world」が表示されます。

consoleを開くと、source mapでtsのコードが追えることが確認できます。

## まとめ

今からReact試すならTypeScriptですよね！
どんどんReactしていきましょう。