webpack4 + Babel7の環境構築

webpack+Babelの環境設定をしていたら、いろいろな記事が出てきましたが、webpack4とBabel7を考慮した記事が少なく、またそんな記事があってもとても細かく書かれていて読みづらく感じたので、この記事では自分なりにまとめました。

## Node.jsが入っているか確認
```
$ node -v
```

## package.json ファイルを作成
```
$ npm init
```

いろいろ出るけど`enter`を押します。

これからnpmでパッケージをインストールしていきます。よく使うインストールの仕方として2つの方法があります。

## --save-devと--saveを区別してpackageをインストール
```
$ npm i --save-dev [package] 
$ npm i --save [package]
```

**--save-dev**: デバッグ系（テストツール）はdevDependenciesに入れる
**--save**: アプリケーションの中で必要なpackage（例えば日付解析:moment）はdependenciesに入れる

この2のインストール方法の違いは、大まかにいうと上記のような区別です。

では、`webpack`を npm install してみます。公式サイトよれば以下のように説明されています。
>Webpackは、最新のJavaScriptアプリケーション用の静的なモジュールバンドラです。 webpackがアプリケーションを処理するとき、内部的に依存性グラフが作成され、プロジェクトに必要なすべてのモジュールがマップされ、1つ以上のバンドルが生成されます。

今後開発を進めていくと、様々なファイルが作成されます。例えば、html,image,css,scssなど。このような複数のファイルは、それぞれのファイルに読み込みされていたりimportさせていたり、複雑な依存関係となっています。webpackは、様々なモジュールをまとめてくれており, 複数のファイルをまとめて1つのファイルにして出力してくれるもの 程度の理解で進みたいと思います。

`webpack`は今後の開発中に必要なモジュールバンドラなので、`--save-dev`オプションをつけてインストールします。

```
$ npm i --save-dev webpack
```

また、webpackコマンドを使うために必要なwebpack-cli（webpack4から必要になった）をインストールします。

```
$ npm i --save-dev webpack-cli
```

## webpack.config.jsを作成

`node_modules`フォルダと同じ階層に作成し、以下の内容を記載します。

```webpack.config.js
module.exports = {
  mode: 'development',
  entry: __dirname + "/src/index.js",
  output: {
    path: __dirname + 'dist', 
    filename: 'bundle.js',
  }
}
```
私が記載した順番で補足をしていきます。
1. **entry** : このファイルから解析をスタートするという指定
2. **__dirname** : コンパイルする対象のファイルを指定。これをつけることで絶対pathにできます。ここで、その対象のファイルをindex.jsとします。srcフォルダ内にindex.jsを作成しましょう。
3. **mode** :development, production, noneの3種類があります（webpack4から追加された）
4. **output**
    - path :コンパイル後の出力ファイルの場所指定
    - filename : 出力ファイル名

この順番で`webpack.config.js`ファイルを作成していきました。

## webpack-dev-serverをインストール
```
$ npm i —-save-dev webpack-dev-server
```

## babel系をインストール
Babel7になったので、@がついているものをインストールします。

```
$ npm i --save-dev babel-loader @babel/core @babel/cli @babel/preset-env
```


babel-loader : Babelとwebpackを使用してJavaScriptファイルを翻訳する
@babel/core : Babelのコンパイラのコア
@babel/cli : Babelコマンドを使えるようにするコマンドラインインタフェース
@babel/preset-env : targetで指定したブラウザやNode.jsのバージョンに合うように、Javascriptを変換してくれるpreset

### 次に、@babel/polyfillをインストールしましょう。
**@babel/polyfill**はかならず、**--save**でdependenciesにインストールしましょう。

```
$ npm i --save @babel/polyfill
```

@babel/polyfill : ES6の新しい機能などを利用するためのES5向けのライブラリ。jsにインポートして使う。プリセットではない。

## webpack.config.jsにmoduleについての記載を追加
webpack4からrulesと書くようになったことに注意してください。rulesにはdictionaly形式で書いていきます。(ファイルの拡張子ごとにruleを書いていきます)
今回は.jsファイルについてのruleを書きます。

```webpack.config.js
module.exports = {
  mode: 'development',
  entry: __dirname + "/src/index.js",
  output: {
    path: __dirname + 'dist',
    filename: 'bundle.js',
  },
  // 以下追記箇所(1)
  module: {
    rules:[
      {
        test: /\.js/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader',
          },
        ]
      }
    ]
  },
  // 以下追記箇所(2)
  resolve: {
    modules: [`${__dirname}/src`, 'node_modules'],
    extensions: ['.js'],
  }
}
```

### 追記箇所(1)
* test: .jsファイルに対してルールを書く
* exclude: このルールを適用しないフォルダがある場合は書く
* use: jsファイルはbabelを使ってloadしてくださいという設定


### 追記箇所(2)

同時にresolveも追加しました。ぬかりなくすべてのmoduleを読み込みしてほしいという命令。モジュールを読み込む時に検索するディレクトリを設定します。

開発を進めていけばそのうちsrcの下にもmoduleを作成していく、node_modulesもモジュールということで絶対pathで指定したsrc直下とnode_modulesを指定しました。

## .babelrcファイルを作成
package.jsonと同じ階層に作成し、以下の内容を記載します。

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

これで、webpack4とbabel7の設定はOKです。loaderがちゃんと動いているのか確認したいので、index.jsにES6で適当に何か書いてみましょう。

```index.js
import '@babel/polyfill'

let num = 1;
console.log(num);
```

これをコンパイルします。ターミナルで以下のコマンドを入力します。

```
$ ./node_modules/.bin/webpack
```
ファイルがバンドルされdistが作成されてbundle.jsファイルができあがります。

bundle.jsを見ると、`let → var`に変わっているのが確認できたので、問題なく環境設定ができていることがわかりました。


めでたしめでたし。