webpack入門（Node.jsの導入からjsファイルのバンドルまで）

# はじめに
業務でwebpackを使用する機会があるので、学習したことをまとめていきます。
今回は、Node.jsのインストール・jsファイルのバンドル~~・Loaderを使ってcssのバンドルを~~実際に行います。

※一度にいろいろやると分からなくなるので、今回はjsファイルのバンドルまで行います。次回Loaderを用いてcssやscssファイルをバンドルする手順についてまとめます。

以前の学習まとめはこちら[package.jsonとpackage-lock.jsonのバージョン指定や必要性について](https://qiita.com/sasao3/items/b794c1e44715bb6f834f)

# 今回使用するツールなどのバージョン

- Node.js：12.16.3
- npm：6.14.4
- webpack: 5.58.1
- webpack-cli: 4.9.0



# webpack導入の前に
図が多くわかりやすかったので、こちらの記事を見ておくとイメージが少しつくかと思います。
[webpack学習の基本のき](https://www.fundely.co.jp/blog/tech/2020/01/22/180037/)

# 前準備
## １．Node.js/npmの導入
webpackを使用するには、Node.jsが必要になるためまずはインストールをしていきます。Node.jsをインストールする際に、npmもインストールされます。

[Node.jsダウンロードサイト](https://nodejs.org/ja/download/)

インストールが完了したら、以下のコマンドで確認しバージョンが表示されればOK。

```
node -v
v12.16.3
```

```
npm -v
6.14.4
```

## ２．プロジェクトディレクトリの作成とpackage.jsonの作成
Node.jsがインストールできたら、次はプロジェクト用のディレクトリを用意します。

作成したディレクトリに移動したら、以下のコマンドでpackage.jsonを作成します。
色々設定について聞かれますが、特に気にせずEnterでOK。

```
npm init
```

上記のようにすべてEnterで問題ない場合は、以下のようにオプションを付けることで何も聞かれることなくpackage.jsonが作成できます。

```
npm init -y
```

## ３．webpack/webpack-cliのインストール
今回はwebpackを使いたいということで、webpackとwebpack-cliの２つをとりあえずインストールします。webpackとwebpack-cliについての細かいところはこちらを
→[webpack](https://www.npmjs.com/package/webpack)/[webpack-cli](https://www.npmjs.com/package/webpack-cli)
以下のコマンドを実行。

```
npm install --save-dev webpack
```

```
npm install --save-dev webpack-cli
```

インストールを行うと、ディレクトリ内に`node_modules`が作成されます。


## ４．webpack.config.jsとバンドルするためのjsファイルを準備
`webpack.config.js`とは、webpackの設定ファイルです。
このファイルで、エントリポイントやバンドルしたファイルの出力場所などなどを記載していきます。

まずは、エントリポイント用のjsファイルを作成します。
今回は`index.js`とします。中身に関しては後ほど。


次に、webpack.config.jsを作成します。

内容は以下のように。

```js:webpack.config.js
const path = require('path')

module.exports = {
    entry: path.resolve(__dirname, "index.js"),  //エントリポイントであるファイルのパスを指定
    output: {
        path: path.resolve(__dirname, 'dist'),  //バンドルしたファイルの出力先のパスを指定
        filename: 'bundle.js' //出力時のファイル名の指定
    }
}
```

```js
const path = require('path')
```
`path`は、Node.jsにデフォルトであるモジュール。
`path.resolve()`は、引数のパスをもとに絶対パスを返します。
公式ドキュメントを読んだのですがよくわからなかったので以下のサイトも参考にしました。

>絶対パスを返す。
引数の後ろから順に評価、結合していく。
途中で絶対パスが完成したら結合途中でも処理を抜ける。 

> path.resolve('/a', '/b', '/c');
=> /c

> path.resolve('/a', '/b', 'c');
=> /b/c

> path.resolve('/a', 'b', 'c');
=> /a/b/c

> path.resolve('a', 'b', 'c');
=> current_path/a/b/c

> path.resolve(__dirname, 'a', 'b', 'c');
=> current_path/a/b/c

> 引数の右から順位処理をしていき、”/”に当たった時点で絶対パスが作成されるため、そこで処理が終了する。つまり引数の文字列の先頭に”/”がある場合、そこまでで処理が終わる。
最後まで絶対パスができなかった場合は実行時のcurrent_pathを付けて返す。
引用元：[path.resolve()の使い方](http://once-and-only.com/programing/javascript/path-resolve%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9/)

そのため、今回であれば
entryは、`current_path/index.js`
output（出力する際に作成される）は、`current_path/dist/bundle.js`
というようになります。


参考
[Node.js v12.22.7 Documentation](https://nodejs.org/docs/latest-v12.x/api/path.html#path_path_resolve_paths)



現在のディレクトリ構成はこんな感じ

```
practice
 ├─ node_modules
 ├─ index.js
 ├─ package.json
 ├─ package-lock.json
 └─  webpack.config.js
```

先ほどの、`webpack.config.js`の出力設定だとpracticeディレクトリの直下に`dist`というディレクトリが作成され、そこに`bundle.js`というバンドルファイルが作成されます。


## ５．html、jsファイルを用意する
前準備は大体できたので、あとはバンドルする用のファイルを用意する。

js用ディレクトリを用意し、jsディレクトリには、sum.jsとdevide.jsを作成します。

現在のディレクトリ構成は以下の通りです。

```
practice
 ├─ node_modules
 ├─ src
 |  └─ js　
 |     ├─ devide.js
 |     └─ sum.js
 ├─ index.html
 ├─ index.js
 ├─ package-lock.json
 ├─ package.json
 └─  webpack.config.js
```

各ファイルに処理を記載します。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>webpack学習</title>
    <!-- バンドルしたファイルを読み込む -->
	<script src="dist/bundle.js"></script>
</head>
<body>
  <p class="message">webpack学習中！！</p>
</body>
</html>
```

```js:devide.js
export default function hello(a, b) {
    return a / b;
}
```

```js:sum.js
export default function sum(a, b) {
    return a + b;
}
```

```js:index.js
import sum from './src/js/sum.js';
import devide from './src/js/devide.js';

var a = 10;
var b = 2;

var result = 'sum()の結果は' + sum(a, b) + ' devide()の結果は' + devide(a, b);
alert(result);
```

これでファイルの準備はOK。
今回は、足し算結果を出力する処理が記載されたsum.jsと割り算結果を出力する処理が記載されたdevide.jsをバンドルする。

`webpack.config.js`で設定したエントリーポイントが`index.js`であるため、このファイル内でバンドルしたいjsファイルを読み込む。

## ６．scriptsにコマンドを追加
package.jsonのscriptsでコマンドを追加することで、簡単にコマンド実行が出来るようになります。以下のようにコマンドを追加します。

```json:package.json
{
  "name": "practice",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "version": "webpack -v",
    "dev": "webpack --mode development",
    "build": "webpack --mode production",
    "watch": "webpack --mode development --watch",
    "test": "echo \"Error: no test specified\" && exit 1",
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^5.58.1",
    "webpack-cli": "^4.9.0"
  }
}

```
scriptsでは「コマンド名:実際に実行したいコマンド」のように記載します。
基本的に実行するには`npm run コマンド名`で実行します。

試しに、`npm run version`と実行すると、以下のようにwebpackなどのバージョンが確認できます。

```
webpack: 5.58.1
webpack-cli: 4.9.0
webpack-dev-server not installed
```

他の設定したコマンドのざっくりした説明は以下の通り。
`webpack --mode development`は、開発用のビルド
`webpack --mode production`は、本番環境用のビルド
`webpack --mode development --watch`は開発用のビルドで、ファイルの変更を検知して自動でビルドしてくれる。


## 7.いざバンドル！
以下のコマンドでバンドルします。

```
npm run dev
```

バンドルが完了したら、index.htmlをブラウザで確認します。
以下のように、アラートで処理結果が表示されればバンドル成功です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381376/8dbb0aec-58cf-7416-9dca-30c471400a14.png)


# まとめ
今回はNode.jsの導入からwebpackを用いたjsファイルのバンドルまでをやってみました。以前まではwebpackは難しいものというイメージがありましたがわかってくると便利そうだなと思いました。

いきなり実務で使われている、webpack.config.jsを見てしまうと設定が色々あってくじけてしまうのでぜひ今回のように少ない設定項目から始めるといいのではないかと思います。