webpackというものを触ってみる - とりあえず導入

# はじめに

仕事ではなかなか触れる事が無いので、プライベートでwebpackというものを触ってみます。  
普段フロント側を実装するときは、昔ながらのゴリゴリにHTML,Js,CSSを記述しているので時代から完全に取り残されていて大変です。
たまにフロント側のFWやライブラリを使ってみようとおもったら、インストールの手順に `npm`が必ず出てきそこから良くわかっていないので、色々勉強です。

# 環境

- windows10 (wsl2)
- node(v16.18.0)
- yarn(1.22.19)

# webpackのインストール

```sh
# プロジェクト作成
$ yarn init -y

# webpackインストール
$ $ yarn add -D webpack webpack-cli
```

これだけでJsをまとめられるらしいです…？

# ひとまずJsを用意する

以下の3つJsファイルを用意します。

```js:./src/js/sum.js
export function sum(num1 = 0, num2 = 0) {
    console.log(`${num1} + ${num2} = ${num1 + num2}`);
}
```
```js:./src/js/minus.js
export function minus(num1 = 0, num2 = 0) {
    console.log(`${num1} - ${num2} = ${num1 - num2}`);
}
```
```js:./src/index.js
import sum from "./js/sum";
import minus from "./js/minus";

sum();
sum(5, 4);
minus();
minus(4, 2);
```

この時点でのディレクトリ構成は以下です。

```sh
$ tree -I node_modules
.
├── package.json
├── src
│   ├── index.js
│   └── js
│       ├── minus.js
│       └── sum.js
└── yarn.lock
```

# コンパイル

というわけで用意したJsをコンパイルしてみます。

```sh
$ npx webpack
asset main.js 157 bytes [emitted] [minimized] (name: main)
orphan modules 198 bytes [orphan] 2 modules
./src/index.js + 2 modules 306 bytes [built] [code generated]

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value.
Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/

webpack 5.74.0 compiled with 1 warning in 215 ms
```

何やら警告が出てきますが、とりあえずコンパイルできました。

```sh
$ tree -I node_modules
.
├── dist
│   └── main.js
├── package.json
├── src
│   ├── index.js
│   └── js
│       ├── minus.js
│       └── sum.js
└── yarn.lock

3 directories, 6 files
```

`./dist/main.js` がコンパイルの結果出力されたJsファイルです。
中を見てみると以下の様になっています。

```js
(()=>{"use strict";function o(o=0,n=0){console.log(`${o} + ${n} = ${o+n}`)}function n(o=0,n=0){console.log(`${o} - ${n} = ${o-n}`)}o(),o(5,4),n(),n(4,2)})();
```

ぱっと見、よくわかりませんがとりあえずJsが統合されていそうです。

# `package.json` に `scripts` を追加

統合されたJsの確認は一旦置いておいて、先程の `npx webpack` を楽に実行する為 `package.json` を編集します。

```json:./package.json
{
  "name": "20221014_webpack",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "build": "webpack"
  },
  "devDependencies": {
    "webpack": "^5.74.0",
    "webpack-cli": "^4.10.0"
  }
}
```

`"scripts": {...}` を追記しました。 これで `yarn build` で先程と同じコンパイルを実施できます。

# `webpack.config.js` を作成

ここまでwebpackの設定等は特に行っていませんので、これまでの動作はデフォルトの設定が利用されています。
しかし、`webpack.config.js` を利用し設定を記述する事であれこれと動作を制御する事ができます。
ひとまず、以下の様に設定します。

```js:./webpack.config.js
module.exports = {
    // モード
    // development:ソースマップが有効
    // production:コード圧縮
    mode: "development",
    
    // エントリーポイントのJs
    entry: `./src/index.js`,

    // コンパイルした結果を出力する先の設定
    output: {
        path: `${__dirname}/dist`,
        filename: `main.js`
    }
}
```

これでコンパイルしてみます。
`mode` を設定したので、先程出ていた警告は無くなっていると思います。
ディレクトリ構成は以下となります。

```sh
$ tree -I node_modules
.
├── dist
│   └── main.js
├── package.json
├── src
│   ├── index.js
│   └── js
│       ├── minus.js
│       └── sum.js
├── webpack.config.js
└── yarn.lock

3 directories, 7 files
```

`webpack.config.js` が増えた事以外は対して変わりませんが、 `./dist/main.js` の内容が大きく変わっています。
`mode:"development"`にした事でソースマップが有効となっているJsが作成されています。

# ローカルサーバーでの動作確認

ようやくですが、コンパイルしたJsの動作を確認してみます。
**webpack-dev-server**なる便利なものがあるらしく、利用してみます。

```sh
# インストール
$ yarn add -D webpack-dev-server
```

次に `webpack.config.js` にローカルサーバーの設定を記述します。

```js:./webpack.config.js
module.exports = {
    // モード
    // development:ソースマップが有効
    // production:コード圧縮
    mode: "development",

    // エントリーポイントのJs
    entry: `./src/index.js`,

    // コンパイルした結果を出力する先の設定
    output: {
        path: `${__dirname}/dist`,
        filename: `main.js`
    },

    // webpack-dev-serverの設定
    devServer: {
        static: "dist",     // 公開するルートディレクトリ
        open: true,         // サーバー起動後自動でブラウザ立ち上げ
        // port: 8081          // ポートを指定したい場合に記述。 デフォルトは8080。
    }
}
```

次に動作確認用のページを `./dist` 配下に作成します。

```html:./dist/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.0">
    <title>Index</title>
    <script src="./main.js"></script>
</head>
<body>
    <h1>webpackというものを触ってみる</h1>
</body>
</html>
```

では、ローカルサーバーを立ち上げてみます。

```sh
$ npx webpack serve
```

先程用意した `index.html` のページが表示されると思います。
開発者ツールのコンソールに以下の様に表示されていると、まとめたJsが動作している事を確認できます。

> 0 + 0 = 0
5 + 4 = 9
0 - 0 = 0
4 - 2 = 2

最後に、先程のローカルサーバー起動のコマンドも `package.json` に記述しておきます。

```json:./package.json
{
  "name": "20221014_webpack",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "build": "webpack",
    "serve": "webpack serve"
  },
  "devDependencies": {
    "webpack": "^5.74.0",
    "webpack-cli": "^4.10.0",
    "webpack-dev-server": "^4.11.1"
  }
}
```

`"serve": "webpack serve"` を追加しました。
これで `yarn serve` でローカルサーバーを実行できます。

尚、このローカルサーバーですがファイルを保存すると表示が更新されて即座に反映されます。
すごい。

# この時点でのディレクトリ構成等

```sh
$ tree -I node_modules
.
├── dist
│   ├── index.html
│   └── main.js
├── package.json
├── src
│   ├── index.js
│   └── js
│       ├── minus.js
│       └── sum.js
├── webpack.config.js
└── yarn.lock

3 directories, 8 files
```

```json:./package.json
{
  "name": "20221014_webpack",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "build": "webpack",
    "serve": "webpack serve"
  },
  "devDependencies": {
    "webpack": "^5.74.0",
    "webpack-cli": "^4.10.0",
    "webpack-dev-server": "^4.11.1"
  }
}
```

```js:./webpack.config.js
module.exports = {
    // モード
    // development:ソースマップが有効
    // production:コード圧縮
    mode: "development",

    // エントリーポイントのJs
    entry: `./src/index.js`,

    // コンパイルした結果を出力する先の設定
    output: {
        path: `${__dirname}/dist`,
        filename: `main.js`
    },

    // webpack-dev-serverの設定
    devServer: {
        static: "dist",     // 公開するルートディレクトリ
        open: true,         // サーバー起動後自動でブラウザ立ち上げ
        // port: 8081          // ポートを指定したい場合に記述。 デフォルトは8080。
    }
}
```

# おわりに

とりあえずJsをまとめて、まとめたJsが動いているところ迄確認できました。
次はBabelというものを導入してみたいと思います。

# 参考

https://ics.media/entry/12140/