webpackの勉強

# はじめに
以下の記事を参考にしてます！
この記事で使っているwebpackのバージョンは４以上なので、一部古い情報から更新してます。
開発用のtwitterのアカウント作ったのでよかったらフォローしてね！[twitter: @susiyaki_dev](https://twitter.com/susiyaki_dev)

## 参考

> [webpack入門 - Qiita](https://qiita.com/hika7719/items/76e87b6ecf308516c514)
> [これから始めるwebpack - webpackの基礎知識 \| CodeGrid](https://app.codegrid.net/entry/2017-webpack-basics-1)

# 勉強のきっかけ

周りのエンジニアの会話でwebpackという単語が出てきていたが、自分だけ理解ができていないようでついていけなかった。
また、最近勉強しているVue.jsの開発では、Vue CLIが勝手に処理してくれるようだが、理解するのは大事だと思ったのでLet's study!

# webpackとは

## webpackの役割

- javascriptのファイルを一つにまとめる役割。
- まとめる過程で、他の設定ファイルを用いてes6やReactなどさまざまなディストリビューションで書かれたものをトランスパイルしてブラウザで閲覧可能にする。

## webpackの開発経緯

開発以前のモジュールシステムには、BrowserifyやGrunt、glupを組み合わせたモジュールシステムの組み合わせがポピュラーであった。
しかし、これらは一つのファイルに結合して出力するという形式であったため、大規模開発の場合には、

- 初回アクセス時のユーザの読み込み時間が莫大になってし
まう
- 少しの変更でもプロジェクト全体の処理が更新されるためキャッシュが非効率になる

と言った問題があった。
これを背景として、アクセスページに依存関係のあるコードだけが含まれるファイルを読み込むためのwebpackが開発された。

# 使い方

## パッケージの準備

### `npm init`でpackage.jsonの作成

`npm init`時の対話内容

|質問|説明|
|---|----|
|package name: (sample_webpack)|package名(default: カレントディレクトリ名)|
|version: (1.0.0)|バージョン設定|
|description:|packageの概要説明|
|entry point: (index.js)|他のjsを参照するファイルの設定(default: index.js)|
|test command:|testコマンドを用いる場合入力|
|git repository:|githubなどのリポジトリを設定する場合入力|
|keywords:|npm公開時等に使用するキーワードの設定をする場合入力
|author:|npm公開時に表示される作者情報を設定する場合入力|
|license: (ISC)|npm公開時に適用する権利情報を設定する場合入力|

### webpackの導入

`npm i -D webpack webpack-cli`
を実行。webpackのバージョンが4以上の場合はwebpack-cliが必要

注釈`-D = --save-dev`

### babelのインストール

本サンプルで用いるbabelとはes6をトランスパイルするモジュール。
`npm install babel-core babel-loader@7 babel-preset-es2015 -D`
webpackのバージョンが４以上の場合は`babel-loader@7`でバージョン指定しなきゃいけないっぽい

`touch webpack.config.js`

## 設定ファイルの編集

### webpack.config.js

このファイルにwebpackコマンドを実行した際の動作を記述する。  
形式はjson。

```webpack.config.js
module.exports = {
  entry: './index.js',          // 他のjsファイルを参照しているファイル
  output: {   
    path: __dirname + '/dist',  // 出力ファイル先
    filename: 'bundle.js'       // 出力ファイル名
  },
  
  module: {
    rules: [                    // webpackのバージョンが4未満の場合は rules -> loaders
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader",
        query: {
          presets: ['es2015']
          }
        }
      }
    ]
  }
};
```

この例では、webpackコマンドを実行すると、`dist/bundle.js`が生成される。  
module内では、`loaders`で使用するモジュールとして`babel-loader`を指定している。また、対象ファイルを`test`で、除外するファイルを`exclude`で指定する。  
`query`には`loader`に渡す引数を書く。

### package.json

``` package.json
   {
    "name": "sample_webpack",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1",
 +  // webpackのバージョンが4未満の場合は webpack --mode development --open -> webpack
 +    "build": "webpack --mode development --open"            
    },
     "author": "",
     "license": "ISC",
     "devDependencies": {
       "babel-core": "^6.26.3",
       "babel-loader": "^8.0.5",
     "babel-preset-es2015": "^6.24.1"
     }
   }
```

# 使用方法

## ソースファイルの準備 

ディレクトリ、ファイルを作成する
`touch index.html index.js`
`mkdir src`
`touch src/foo.js`

内容はこんな以下の通り。

```index.html
<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <script src="./dist/bundle.js"></script>
</head>

<body>
<h1>es6 example</h1>
</body>

</html>
```
ただのテンプレート

```foo.js
export const foo = 'Foo';
```
exportでデータを渡す。（参照可能にするデータを入れ込む)

```index.js
import {foo} from './src/foo'
console.log(foo);
```
importでコンポーネントから利用するデータを持ってくる。
consoleに表示できれば動作確認OK

## いざ実行

`npm run build`で`webpack.config.js`に設定した内容に基づいてビルドしてくれる。

buildされたindex.htmlの実行結果

<img width="1436" alt="実行結果.png" src="https://qiita-image-store.s3.amazonaws.com/0/308296/7a2a654f-875a-03fa-adf7-603af899a7ac.png">

consoleにFooが出ている！