TypeScript+webpackでRxJSを試す

# はじめに

**きっかけは、Angluar...**
AngluarではRxのObservableは無くてはならないものになっています。
その反面RxJSを使ってObservableを返すオブジェクトを自作するという場面が今まであまりありませんでした。(個人的に)
今回は、RxJSで色々試すために、Angluarとは完全に切り離した形で、TypeScript + RxJSが使える環境が欲しかったのでwebpackで構築してみました。その際の手順をメモとして残しておきます。

# npmプロジェクトを作成

プロジェクトを作成します。

```
$ mkdir typescript-webpack-rxjs
$ npm init -y 
```

## ローカルに必要なパッケージをインストール
今回は、typescript、webpackに関してもローカルにインストールしました。
また、TypeScriptのローダーにはawesome-typescript-loaderを使いました。
RxJSを使って見るところまでやるので、RxJS本体をインストールします。

```
$ npm install --save-dev typescript webpack awesome-typescript-loader
$ npm install --save rxjs
```
それぞれのバージョンは以下の通り。

* typescript: 2.6.1
* webpack: 3.8.1
* rxjs: 5.5.2
* awesome-typescript-loader: 3.3.0

# 設定ファイルの作成
## tsconfig.jcon

まずは、awesome-typescript-loaderでのtypescriptのコンパイルに必要なtsconfig.jsonを作成します。
これは、tscコマンドで雛形を作成することが出来ます。

```
$ tsc --init
message TS6071: Successfully created a tsconfig.json file.
```
作成された雛形を次のように編集します。
今回はhtmlとtsそれぞれ1ファイルのみを使用するので、filesにはtsファイル1ファイルのみを記述します。

```json:tsconfig.json
{
  "compilerOptions": {
    "noImplicitAny": true,
    "target": "ES2015",
    "module": "commonjs",
    "outDir": "dist"
  },
  "files": [
    "./src/index.ts"
  ]
}
```

tscのオプションは [TypeScript2系のコンパイラのオプション一覧](https://qiita.com/IganinTea/items/f88bea469bff56cfbda6)という記事に詳しくまとめられていました。

## webpack.config.js
次にwebpackの設定ファイルを作成します。

```
$ touch webpack.config.js  
```

作成したファイルを次のように編集。
エントリポイントの設定と、TypeScriptローダーの設定を行っています。

```js:webpack.config.js
module.exports = {
  entry: './src/index.ts',
  output: {
      filename: './dist/bundle.js'
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.jsx']
  },
  module: {
    loaders: [
      {
        test: /\.tsx?$/,
        loader: 'awesome-typescript-loader'
      }
    ]
  }
};
```

## npm コマンドの設定

今回は、webpackをローカルインストールしているため、npmコマンドから実行できるように設定しておきます。
これで、`npm run build`でwebpackによるビルドが実行されます。

```json:package.json
...
  "scripts": {
    "build": "webpack",
    ...
  },
...
```

# html、typescriptファイルの追加

まずは、コンパイルしたjsを読み込むhtmlと、メインのtsファイルを作成。
最終的なプロジェクトのディレクトリ構成は以下のようになります。

```
.
├── ./dist
│   └── ./dist/bundle.js
├── node_modules
├── ./index.html
├── ./package-lock.json
├── ./package.json
├── ./src
│   └── ./src/index.ts
├── ./tsconfig.json
└── ./webpack.config.js
```

```
$ touch index.html
$ mkdir src
$ cd src
$ touch index.ts
```

# コーディング
実際にTypeScriptでコーディングして、Webpackでコンパイルしてみたいと思います。

今回はブラウザのコンソールに試しに何か表示させる程度のサンプルを作成するので、index.htmlの内容はシンプルに次の通り作成しました。scriptタグでビルド済みのbundler.jsが読み込むだけです。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <script type="text/javascript" src="./dist/bundle.js"></script>
</head>
<body>
  
</body>
</html>
```

まずは、rxをインポートしておきます。
内容としては、1秒ごとに整数をカウントアップしていくObservableを作成し、
それをsubscribeするという至ってシンプルな内容です。
subscribe時にfilterオペレーターを使って、3の倍数または3が付くときだけコンソール出力されるようになっています。(世界の...)

```ts:index.ts
import { Observable } from 'rxjs/Observable';
import 'rxjs/Rx';

let ob$ = new Observable(observer => {
  let count = 0;
  let interval = setInterval(() => {
      observer.next(count++);
  }, 1000);
});

ob$.filter((value: number) => {
  return value % 3 == 0 || String(value).indexOf('3') >= 0;
}).subscribe(value => console.log(value));
```

# ビルド & 確認

先ほど設定したnpmコマンドでビルドをします。

```
$ npm run build
// watchモードの場合は...
$ npm run build -- --watch  
```

index.htmlをブラウザから開き、デベロッパーツールからconsoleを確認すると....

<img width="929" alt="スクリーンショット 2017-11-04 1.30.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/79414/a997747a-3380-5d84-94e7-3849f1be4696.png">


以上です。

# 参考

https://www.typescriptlang.org/docs/handbook/react-&-webpack.html
https://qiita.com/hrloca/items/61ced4d16d6c257ada02
https://qiita.com/erukiti/items/6a82dfd3506e9773d592