TypeScript, webpack, yarnを使ってhtml, jsをバンドルしてlocalhostで動かすまでの手順

typescript, yarn, webpackで環境を作ろうとした際、ハマったので備忘録も兼ねて記事にしたいと思います。
# 最初はyarn
最初はyarn initでpackage.jsonを生成します。
コマンドライン上に表示される質問に答えてけば、よしなにしてくれます。

```
yarn init
```

次に使うパッケージの取得
webpackとwebpack-cliとtypescriptをdevDependenciesにつっこみます。
typescriptとwebpackを使用するのに必要なパッケージとwebpackのtypescript用モジュールを読み込みました。

```
yarn add webpack webpack-cli typescript ts-loader -D
```

# TypeScriptの設定
下のコマンドを打ってtsconfigを生成します。
tsconfigの内容については今回は扱いません。

```
tsc --init
```

# webpackの設定
webpackの設定ファイル`webpack.config.js`を作成します。
以下のようなファイル構成になっていて基本的な`webpack.config.js`とは`ts-loader`を読み込んでいる点が違います。
entryやoutputについては適宜変えてください。



```javascript:webpack.config.js
const path = require('path');
const outputPath = path.resolve(__dirname, "public");

module.exports = {
    mode: 'development',
    entry: './src/index.ts',
    output: {
        filename: 'bundle.js',
        path: `${outputPath}`
    },
    module: {
        rules: [{
            test: /\.ts/,
            use: 'ts-loader',
            exclude: /node_modules/,
        }, ],
    },
    resolve: {
        extensions: ['.ts', '.js'],
    }
};


```

加えて、今回エントリーポイントにしてしたファイルである`src/index.ts`を作成します。

ちなみにこのファイルの書き方については以下の記事がとても参考になりました。

- https://webpack.js.org/guides/typescript/
- https://qiita.com/soarflat/items/28bf799f7e0335b68186


ここまでいけばwebpackコマンドが動くはずです。
以下のコマンドで動かしてみて下さい。
`webpack.config.js`のoutputで指定したフォルダにjsファイルが出力されていれば成功です。

```
yarn webpack
```

# webpack-dev-serverの設定
次にwebpackでローカルサーバーを立ち上げる為webpack-dev-serverというプラグインを導入します。

まずは

```
yarn add webpack-dev-server -D
```
とコマンドを打ってwebpack-dev-serverをインストールします。

その後、`webpack.config.js`の設定に`devServer`という項目を以下のように付け加えます。

```javascript:webpack.config.js
const path = require('path');
const outputPath = path.resolve(__dirname, "public");

module.exports = {
   ...
   ...
   resolve: {
        extensions: ['.ts', '.js'],
    },
  //ここから下を追加
  devServer: {
    contentBase: `${outputPath}/`, //エントリーポイントを指定
    open: true, // ブラウザを自動で開くか否か
    hot: true, // 開発中にCSSとかを変更した時、リロードせずに更新するか否か
    watchContentBase: true // 変更した時自動でリロードされるか否か
  }
};

```

そしたら以下のコマンドを打ってください。

```
yarn webpack-dev-server
```
そしたらローカル環境上にサーバーが立ち上がるはずです。
[http://localhost:8080/](http://localhost:8080/)にアクセスしてみてください。

これでwebpack-dev-serverに関する手順は終了です。

webpack-dev-serverを調べる上で参考にしたのは以下のサイトです。

- https://webpack.js.org/configuration/dev-server/

# HTMLを自動で作成
次は**html-webpack-plugin**を追加します。
これを使うことでoutputで指定したディレクトリの中にindex.htmlが自動で追加されるようになります。

では実際に追加していきます。
まず、以下のコマンドを打ってhtml-webpack-pluginをインストールします。

```
yarn add html-webpack-plugin -D
```

次に`webpack.config.js`に以下の表記を追加します。

```javascript:webpack.config.js

const path = require("path");
const outputPath = path.resolve(__dirname, "public");
const HtmlWebpackPlugin = require('html-webpack-plugin'); //ここを追加

module.exports = {
  ...
  devServer: {
    contentBase: `${outputPath}/`,
    open: true, 
    hot: true, 
    watchContentBase: true 
  },
  //ここより下も追加
  plugins: [
    new HtmlWebpackPlugin() 
  ]
};
```

このように設定できたら以下のコマンドを打ってビルドしてみましょう。

```
yarn webpack-dev-server
```

これでoutputで指定したディレクトリの中にindex.htmlが出力されていればOKです。

この章で参考にしたのは以下のURLです。

- https://github.com/jantimon/html-webpack-plugin

# スクリプトを便利に

次にコマンドを打つのを簡略化してくれるスクリプトを作ります。

package.jsonのscriptsを以下のように指定してください。

```json:package.json
{
  ...
  "scripts": {
    "start": "webpack-dev-server",
    "build": "webpack"
  },
  ...
}
```

これを追加することで```yarn start```を打つことでローカルサーバーが起動し、`yarn build`を打つことでwebpack.config.jsのoutputで指定したディレクトリにファイルがバンドルされます。

これでスクリプトに関しては以上です。

# 全体像

最後にwebpack.config.jsとpackage.jsonの全体を載せておきます。

```javascript:webpack.config.js
const path = require("path");
const outputPath = path.resolve(__dirname, "public");
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  mode: "development",
  entry: "./src/index.ts",
  output: {
    filename: "bundle.js",
    path: `${outputPath}`
  },
  module: {
    rules: [{
      test: /\.ts/,
      use: "ts-loader",
      exclude: /node_modules/
    }]
  },
  resolve: {
    extensions: [".ts", ".js"]
  },
  devServer: {
    contentBase: `${outputPath}/`, //エントリーポイントを指定
    open: true, // ブラウザを自動で開くか否か
    hot: true, // 開発中にCSSとかを変更した時、リロードせずに更新するか否か
    watchContentBase: true // 変更した時自動でリロードされるか否か
  },
  plugins: [
    new HtmlWebpackPlugin()
  ]
};

```

```json:package.json
{
  "name": "example",
  "version": "1.0.0",
  "description": "this is example project",
  "main": "index.js",
  "repository": "https://github.com/exampleUser/exampleProject.git",
  "author": "ExampleUser <user@example.com>",
  "license": "MIT",
  "scripts": {
    "build": "webpack"
  },
  "devDependencies": {
    "html-webpack-plugin": "^3.2.0",
    "ts-loader": "^6.2.1",
    "typescript": "^3.8.3",
    "webpack": "^4.42.0",
    "webpack-cli": "^3.3.11",
    "webpack-dev-server": "^3.10.3"
  },
  "dependencies": {}
}

```

今回の記事はこれで以上となります。
最後までお読みいただきありがとうございました。

---
webpackは始めたばかりなのでまだまだ知識が浅いです。
もし間違いなどがありましたらご指摘よろしくお願いします。