webpack入門して仲良くなりたい～基本編～

#仲良くなりたい

- [基本編](https://qiita.com/gabochi/items/b0bc1d522b12fe124f90)　←今ココ!!
- [開発環境編](https://qiita.com/gabochi/items/caca7cdfaa4a35b73246)
- [Loaders編](https://qiita.com/gabochi/items/1eab632837c9831172f6)
- Plugins編　近日公開予定

開発をしていて、見て見ぬふりをしていた**webpack**…
仲良くなるために何者なのか知ります。

>At its core, webpack is a static module bundler for modern JavaScript applications. When webpack processes your application, it internally builds a dependency graph which maps every module your project needs and generates one or more bundles.

引用: https://webpack.js.org/concepts/

英語はわかめなのでGoogleに頼みます。

・・・

要するに、仲良くなると素敵な人です。

##webpackってなに

###モジュールバンドラ

webpackはモジュールバンドラとしての役割を果たします。
モジュールはアプリケーション内のファイル(jsファイルとかcssファイルとか)
バンドラはまとめる人

JavaScriptアプリケーション内には多くのモジュールから成り立っています。それをバラバラに人間が管理してるとめんどくさいのでwebpackのようなモジュールバンドラが活躍します。素敵です。

### 利点

- リクエスト数の抑制
- ファイルの依存関係を考えなくていい

この2つが大きな利点として考えられます。
この利点を持つため気兼ねなくファイル分割を行うことができます。
モジュールの**再利用性**・**保守性**・**テストの易化**を高めることに集中できます。

#### リクエスト数の抑制

モジュールをまとめることの利点はブラウザに描画するときのリクエストの数が減ることでパフォーマンスの向上を助けます。

~~料理で調味料を入れるときに塩や砂糖を1粒ずつ、しょうゆを1滴ずつ入れたくない~~

まとめたほうが効率がいい！！

#### ファイルの依存関係

ファイル間の依存関係を考えなくていいってことはどんな順番でファイルを読み込ませるのか考えなくてよくなります。

**どの順番でscriptタグ埋め込むんだ??**

```index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script src="js/W.js"></script>
  <script src="js/K.js"></script>
  <script src="js/B.js"></script>
  <script src="js/C.js"></script>
  <script src="js/P.js"></script>
  <script src="js/A.js"></script>
  <script src="js/E.js"></script>
</body>
</html>
```

この作業は控えめに言って**地獄**です…
それを解決してくれる！
依存関係を把握してくれるのがwebpack！！

##遊ぶ準備

### 使うもの

- npm
- webpack
- webpack-cli

```
npm init -y
```
```
npm install --save-dev webpack@4.41.5 webpack-cli@3.3.10 
```

バージョンは最新を使いますが、一応バージョンを指定します
webpackは開発の時に必要なものなので`--save-dev`で入れます

### 基本ファイル構成

```
 webpack-friendly-basic
 ├ ─ ─ node_ modules
 ├ ─ ─ package.json
 ├ ─ ─ package-lock.json
 ├ ─ ─ dist
 │     ├ ─ ─ bundle.js           //アウトプット
 │     └ ─ ─ index.html
 ├ ─ ─ src
 │     ├ ─ ─ js
 │     │     └ ─ ─ app.js        //エントリーポイント 
 │     └ ─ ─ modules
 │           ├ ─ ─ add.js
 │           ├ ─ ─ subtract.js 
 │           ├ ─ ─ multiply.js 
 │           └ ─ ─ divide.js       
 └ ─ ─ webpack.config.js         //webpack設定ファイル
```

### webpack.config.js

webpackの設定を行うファイルです。

```webpack.config.js
const path = require("path");
const outputPath = `${__dirname}/dist`;

// モジュールどうやって出力するか記述します
module.exports = {
  // 実行環境設定
  mode: "development",
  // エントリー ポイントを決めます
  entry: "./src/js/app.js",
  output: {
    // どこにバンドルファイルを出力するか決まます
    path: outputPath,
    // 出力先のファイル名を決めます
    filename: "bundle.js"
  }
};
```
#### mode

このプロパティで使うのは下記の2つだと思います

- development
 - 開発するときはこれ。デバッグしやすくてリロードが早かったりするので
- production
 - 本番環境ではこれ。出力ファイルを圧縮したり、不要なコード(console系とか)削除などできる

`none`というプロパティもありますが、いまいち使い道がわかりませんでした…

#### entry

ファイルの依存関係を解析するファイルの指定を行います。様々なファイルを呼び出す最初のファイル指定してください。

#### output

- path
 - バンドルした結果ファイルをどのディレクトリに出力するか指定
- filename
 - バンドルしたファイル名

### バンドルに必要なファイル

#### modules

バンドル対象となるファイルを準備します。

```add.js
export function add(a, b){
   console.log(a + b);
}
```
```subtract.js
export function subtract(a, b){
   console.log(a - b);
}
```
```multiply.js
export function multiply(a, b){
   console.log(a * b);
}
```
```divide.js
export function divide(a, b){
   console.log(a / b);
}
```

#### entryファイル

```app.js
import { add } from "../modules/add";
import { subtract } from "../modules/subtract";
import { multiply } from "../modules/multiply";
import { divide } from "../modules/divide";

add(1, 2);
subtract(2, 1);
multiply(3, 2);
divide(10, 2);
```

#### distディレクトリ
ここに、モジュールがバンドルされたか確認するためのhtmlファイルを用意します。
`bundle.js`はbuild時に作成されるので気にしなくてよい

```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>
  </head>
  <body>
    <p>webpack Friendly!!</p>
    <script src="./bundle.js"></script>
  </body>
</html>
```
##動かしてみる

### buildする

buildするには以下のコマンドを実行させてください

```
npx webpack
```

`npx`は実行するパッケージのpathを指定しなくても勝手に探して実行してくれるみたい
以下のような画面が出たらバンドルが成功しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251047/14a764c8-bba7-5967-db17-bd397b00fb12.png)

ブラウザで`index.html`を確認してみます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251047/6864806e-a369-44bd-501a-93d45f9a5c2b.png)

chromeの開発者ツールを開いて、ネットワークを見てみると読み込まれているファイルは`index.html`と`bundle.js`です。`app.js`や`modules`配下のファイルらをバンドルした`bundle.js`が読み込まれています。

## 少しわかった気がする

ここまでは本当に基本的な部分だと思います。
次は、ローダーについて書きます。

何か、ご指摘があれば教えてくれると嬉しいです。