webpackでTypeScriptをトランスパイルする


webpackを使う代表的なシーンの１つがTypeScriptのトランスパイルではないでしょうか。
ここではその手順を簡単にまとめておきます。

webpackの基本的利用方法は[こちら](https://qiita.com/zaburo/items/710ab1cba98daf85ad9b)をどうぞ。

## 準備

では、準備から。node.jsはインストールされているものとします。

### 作業場所の作成

まず、作業場所の確保。ディレクトリ名は何でもいいです。
package.jsonを使いたいのでnpm init -fしておきます。

```bash
mkdir ts-webpack
cd ts-webpack

npm init -f
```

### モジュールのインストール

続いて必要なモジュールのインストール。

```bash
npm install --save webpack webpack-cli typescript ts-loader
```

### 必要ファイルの作成

ここで使うファイルを全て生成しておきます。

```bash
touch index.html index.ts tsconfig.json webpack.config.js 
```

各ファイルの利用用途は、

* index.htmlはトランスパイルしたjsの実行用に用意(bundle.jsとして出力予定）
* index.tsはTypeScriptのファイル
* tsconfig.jsonはtsのトランスパイル条件を指定
* webpack.config.jsはバンドルの条件を指定

という感じです。

### ディレクトリ構造

ここまでの操作でディレクトリ構造は下記のようになっているはずです。

```bash
.
├── bundle.js
├── index.html
├── index.ts
├── node_modules
├── package-lock.json
├── package.json
├── tsconfig.json
└── webpack.config.js
```

## 実装

では各ファイルを編集して行きます。

### index.html

まず、index.html。トランスパイル後に生成されるbundle.jsを読み込んでいるだけです。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
    </head>
    <body>
        <p>typescript webpack test</p>
        <script src="bundle.js"></script>
    </body>
</html>
```

### index.ts

次にindex.ts。トランスパイル前のコードです。
受け取った文字列をHelloを付けて出力しているだけです。引数は返り値にstring型が設定されています。

```ts:index.ts
const Hello = (name: string): string => {
    return "Hello " + name;
}

alert(Hello('hoge'));
```

### tsconfig.json

TypeScriptをどうトランスパイルするかを制御します。理解できなければ、最初は”おまじない”ということで。

```ts:tsconfig.json
{
    "compilerOptions": {
        "target": "ESNext", //変換後の形式
        "module": "CommonJS", //モジュールの呼び出し方
        "noImplicitAny": true //型定義がないものを勝手にanyにしない
    }
}
```

### webpack.config.js

最後にバンドル方法を記述します。

* 入力としてindex.ts
* 出力としてbundle.js
* 処理はts-loaderでやる
* ts, jsは拡張子省ける

といったことを定義しています。

```js:webpack.config.js
module.exports = {
    mode: 'development',
    entry: './index.ts',
    output: {
        path: __dirname,
        filename: 'bundle.js'
    },
    module: {
        rules: [
            {
                test: /\.ts$/,
                loader: 'ts-loader'
            }
        ]
    },
    resolve: {
        extensions: ['.ts', '.js']
    }
}
```

## トランスパイルと動作確認

ではトランスパイルしてindex.htmlで動作を確認してみましょう。

### 準備：scriptsの設定

グローバルにwebpackがインストールされていない状態だと、いちいち

```bash
./node_modules/.bin/webpack
```

という感じでwepackを呼び出す必要があり面倒です。
なのでpackage.jsonのscriptsにコマンドを追加します。
package.json中ではwebpackと書けば./node_modules/.bin/webpackを読んでくれます。

```diff:package.json
{
  "name": "ts-webpack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "dependencies": {
    "ts-loader": "^6.2.1",
    "typescript": "^3.7.3",
    "webpack": "^4.41.2",
    "webpack-cli": "^3.3.10"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
+    "start": "webpack"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
```

>webpack --watchとすると変更を監視してトランスパイルを実行してくれます。

### トランスパイル

```bash
npm start
```

>npm run startでもよい。start, test, stopはaliasが設定されているためnpm xxxで呼び出せる。

### 動作確認

実用性はさておきindex.htmlを開くとalertが表示されました（tsで書いたものがjsとなり実行されています）。

![スクリーンショット 2019-12-08 7.25.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/abe43477-1172-44df-b79f-3ed08ca6741c.png "スクリーンショット 2019-12-08 7.25.54.png")

簡単ではありますが、webpackを利用する典型的な利用シーンの１つなので理解してスムーズに設定できるようにしておいたほうがいいでしょう。