Webpackって何をしてくれるの？

#はじめに
webpackの勉強をしたのでまとめてみました。

#webpackとは
公式サイトのイメージ通り
![スクリーンショット 2020-05-08 10.53.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273496/5f20017b-7beb-d585-ef9d-8219fea51f85.png)

CSSやJSファイル、画像などのあらゆるファイルを1つのファイルにまとめてくれるモジュールバンドラのことです。

似たような役割を持つビルドツールとして
Gulp,Parcel,Rollup,Browserifyがあります。

#webpackを使用するメリット
webpackを使用することで得られるメリットの1つに
大量のjsやcssなどのファイルが1つにまとめられるため、リクエストを投げる回数が大幅に減るというものがあります。
大量のリクエストがあった場合、レンダリングまでの時間が長くなってしまうので、速度改善にもつながるかと思います。

またjsでは先に別のjsを読み込んでおかないと動作しないなどの問題が起こり得ますが、1つにまとまられていることで、js同士の依存関係を気にする必要がないというメリットがあります。

## 使ってみる

### 最終的なディレクトリ構成
```
project
├ dist
│  ├ index.html
│  └ main.js
├ node_modules
├ src
│  ├ index.js
│  ├ hoge.js
│  └ style.css
├ .babelrc
├ webpack.config.js
├ package.json
└ package-lock.json
```

###まずはインストール

```bash
$ npm install webpack webpack-cli --save-dev
```
webpackは開発環境用のツールなのでdevelop環境でしか使わないように--save-devオプションを指定します。


### 設定ファイルの用意

```js:webpack.config.js
const path = require('path')
module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'main.js'
  }
}
```
require('path')はpathをいい感じに絶対pathに変換してくれるnodemoudleです

entryにはmainとなるjsのファイルを記述し
outputには出力するjsのpathやファイル名を記述します。


### webpackでbuildするようのファイルを用意
```html:index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>webpack</title>
</head>
<body>
HogeHoge
<script src="./dist/main.js"></script>
</body>
</html>
```

```js:hoge.js
export function hoge() {
  console.log('hoge')
}
```
```js:index.js
import { hoge } from './hoge'

hoge()
```

### webpack用のscriptを用意

```json:package.json
  "scripts": {
    "build": "webpack --mode development"
  }
```

package.jsonを編集しコマンドでbuildできるように設定します。

###実行
```bash
$ npm run build
```
###実行結果

```bash
Hash: 6f2ffec3117bf5ca15db
Version: webpack 4.43.0
Time: 45ms
Built at: 2020-05-13 22:07:41
  Asset     Size  Chunks             Chunk Names
main.js  4.5 KiB    main  [emitted]  main
Entrypoint main = main.js
[./src/hoge.js] 48 bytes {main} [built]
[./src/index.js] 38 bytes {main} [built]
```

dist以下にmain.jsが生成され、htmlを開いたときにconsoleにhogeが出力されていたら成功です。

## webpack-dev-serverって何？
vueとか勉強していたらよく出てくるwebpack-dev-server
勉強するまでwebpackとの違いもいまいちわかってなかったですが
フロントエンド開発における開発用のwebサーバーの役割をになってくれるものです。
build前のjsを変更すると即座に反映してブラウザをリロードしてくれたりするのでかなり便利です。

### webpack-dev-serverのインストール
```bash
$ npm install --save-dev webpack-dev-server
```
package.jsonを合わせて編集します

```json:package.json
  "scripts": {
    "build": "webpack --mode development",
    "start": "webpack-dev-server --mode development"
  }
```
webpack.config.jsの編集

```js:webpack.config.js
module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'main.js'
  },
  devServer: {
    // 公開するファイルのドキュメントルートを指定
    contentBase: path.resolve(__dirname, 'dist'),
    // サーバー起動時に自動でブラウザを開く設定
    open: true
  }
}
```

###実行
```
$ npm run start
```

###実行結果

```[built]
[./src/hoge.js] 48 bytes {main} [built]
[./src/index.js] 38 bytes {main} [built]
    + 19 hidden modules
ℹ ｢wdm｣: Compiled successfully.
```
この状態でlocalhost:8080にアクセスすることで無事htmlが表示できていればOKです
試しにjsを変更すると検知されてconsoleに表示されている文字列が変化するかと思います。

## cssをwebpackで読み込んでみる

### インストール
```bash
$ npm install --save-dev style-loader css-loader
```
cssをwebpackを使ってで読み込むためにはstyle-loaderとcss-loaderが必要です

### 設定を記述
```js:webpack.config.js
module.exports = {
  // entryとか諸々の処理
  module: {
    rules: [
      {
        test: /\.css$/,
        // loaderはしたから実行されるから読み込み順が重要
        use: [
          'style-loader',
          'css-loader'
        ]
      }
    ]
  },
```
rulesに諸々の設定を書いていきます。
testにはファイル名を指定し
useには使用するパッケージを書いていきます。

css-loaderはcssをJavaScriptに変換する処理
style-loaderはJavaScriptに変換されたスタイルを適用させる処理を行うものなので順番を変えるとうまく動かないので注意です。
###読みこむcssを準備

```css:style.css
body {
  font-size: 200px;
}
```

### jsで読み込むために一文を追加

```js:index.js
import './style.css'
```

これでcssが読み込まれHTMLのデザインが変化するとOKです

## babelを使用してみる

### babelとは？

簡単に説明すると、JSの最新の記法で書かれたもの(ES6以降)を古い記法（ES5）に変換してくれるツールです。
ES6だとIEなど動作しないブラウザがあるのでそれぞれの環境で確実にJSが動くことを保証するために使用されます。


### babelのインストール

```bash
$ npm install --save-dev babel-loader @babel/core @babel/preset-env
```

### babelの設定を書く

```js:.babelrc
{
  "presets": ["@babel/preset-env"]
}
```

```js:webpack.config.js
{
  test: /\.js$/,
  exclude: /node_modules/,
  use: {
    loader: 'babel-loader'
  }
}
```
rulesに追加で書いてください

### 適当にES6以降のjsを書いてみる

```js:hoge.js
export function hoge(number) {
  console.log('hoge')
  const numbers = [1, 2, 3]
  console.log(...numbers)
  const square = num => num ** 2
  console.log(square(number))
}
```

### 実行

```
$ npm run start
```

### 確認

```js
function hoge(number) {\n  var _console;\n\n  console.log('hoge3');\n  var numbers = [1, 2, 3];\n\n  (_console = console).log.apply(_console, numbers);\n\n  var square = function square(num) {\n    return Math.pow(num, 2);\n  };\n\n  console.log(square(number));\n}
```
ブラウザからmain.jsを確認して、該当箇所がes5に変換されていれば成功です！


以上、なんとなく今までwebpackを使っていた人がちょっと勉強してみたのをまとめてみた記事でした