Babelとwebpack入門

# 概要
Babelやらwebpack。

なんとなく理解はしているものの、
環境構築の際には、毎度他の記事を参考にして乗り切っていました。

しかし、公式を見ればさらっと構築できるレベルには知識が欲しくなり、
基礎を記事にまとめました。

公式の英文が辛い方はぜひ、最初の一歩にしてみてください。

# Babel
## とは
公式より
>Babel is a JavaScript compiler.

JavaScriptのコンパイラ。
次世代のJSの記載を古いものに変換して、最新のコードを書きつつも、
様々なブラウザで動くようにできる。

## babel-core
Babelのコアなんでしょう。
これだけだと特に何もしてくれない。

## babel-polyfill
コンパイラが頑張っても、補いきれない機能(Promiseとか)をポリフィルで足す。

## babel-cli
名前からわかりそうですが、babelコマンドを使えるようにしてくれます。

### cliを使ってみる
```bash:インストール
npm install -D babel-cli
```

※babel-coreは付属で付いてきます

```js:index.js
const hoge = val => val + 1;
console.log(hoge(1));
```

```bash:実行
$ ./node_modules/.bin/babel index.js

const hoge = val => val + 1;
console.log(hoge(1));
```

おや、何も変わっていませんね。

## ここまでで
公式より
>Now, out of the box Babel doesn’t do anything. It basically acts like const babel = code => code; by parsing the code and then generating the same code back out again.
>
>You will need to add some plugins for Babel to do anything (they affect the 2nd stage, transformation).

上記二つの段階だと、解析までしかしてくれないようです。
変換を行うために、プラグインが必要とのこと。

## Presets
プラグインは、独自に組み立てられるようですが、

>**Official Presets**
>We’ve assembled some for common environments:
>
>Each yearly preset only compiles what was ratified in that year. babel-preset-env replaces es2015, es2016, es2017 and latest

公式は、いくつかの汎用的なものを用意してくれているようです。

### babel-preset-env
>Babel preset that automatically determines the Babel plugins you need based on your supported environments. Uses compat-table


[compat-table](https://kangax.github.io/compat-table/es6/)を見て、
サポートされている環境に基づいてプラグインを自動で選んでくれるようです。
すごい。

#### .babelrc
プリセットの設定はこのファイル(JSON)に集約するようです。

```json:.babelrc
{
  "presets": ["env"]
}
```

上記は特に環境を指定していないため、babel-preset-latestを採用するようです。
早速変換して見ましょう。

```bash
npm install -D babel-preset-env
```

```bash
$ ./node_modules/.bin/babel index.js 

"use strict";

var hoge = function hoge(val) {
  return val + 1;
};
console.log(hoge(1));
```

※-oオプションでファイル出力もできます

変換されてますね！

細かい設定は、公式でやり方を見ましょう！
https://babeljs.io/docs/plugins/preset-env/

## つまり
ちゃんとESxで書きたいよ！っていうときはまず、
解析用のbabel-coreと変換用のプラグイン(presets)を用意すると覚えよう！

# webpack
## とは
モジュールバンドラ。

古の時代、そもそもjsにモジュールシステムはなかった。
大規模な開発になれば、モジュール分割は必須となる。

そして今、モジュールシステムが飛び交う時代であった。
webpackはそんな中のひとつ。

## なぜwebpackなのか
[参考](https://app.codegrid.net/entry/2017-webpack-basics-1)

複数のモジュールを一つに固めて出力していた時代があった(Grunt、Gulp、Browserify)
→大規模になるとファイルがでかくなる
→ロード遅くなったりして、あかん
→webpack「俺は・・・この問題を解決してみせる！」

webpackには他にも様々な機能があるが、
とりあえずwebpack選んでおけば、何かと便利とだけ覚えておけば良さそう。

## 4.0.0~
>Since v4.0.0 webpack does not require a configuration file. Nevertheless, it is incredibly configurable. To get started you only need to understand four Core Concepts:

設定ファイルを必要としないらしい。
が、後述するローダーの関係上、設定ファイルはどうしても必要と思われます。

```bash:とりあえずインストール
npm install -D webpack webpack-cli
```

## コンセプト
①Entry
②Output
③Loaders
④Plugins

### Entry
まず、エントリーポイント(メインとなるモジュール)が必要です。
依存関係を解決するための起点です。

デフォルトでは「./src」を見るようです。

```bash
mkdir src
```

※webpack.config.jsで指定も可

### Output
依存関係を解決した後、結果としてバンドルファイルを出力しなければなりません。

デフォルトでは「./dist」に出力します。

```bash
mkdir dist
```

※webpack.config.jsで指定も可

### ここまでで
さて、これでwebpackが使えそうです。

先ほど作ったindex.jsを外部モジュール化させて、エントリーポイントから呼ぶようにしてみましょう。

```js:src/index.js
import hoge from './hoge.js';
console.log(hoge(1));
```

```js:src/hoge.js
export default val => val + 1;
```

```bash
$ ./node_modules/.bin/webpack
$ node ./dist/main.js

2
```

いい感じですね。

続く、LoaderとPluginに関しては、webpackの便利機能のようです。

### Loaders
エントリーポイントの読み込みに際して、
ローダーを噛ませれば、様々な変換を行える。

Babelを噛ませるとすれば、まさにここになるわけですね。

```bash
npm install -D babel-loader
```

```js:webpack.config.js
module: {
  rules: [
    {
      test: /\.js$/,
      exclude: /node_modules/,
      use: {
        loader: "babel-loader",
        options: {
          presets: ['@babel/preset-env']
        }
      }
    }
  ]
}
```

「jsファイル見つけたら、babel-loader発動しちゃってYO」
みたいなことが書いてあるわけですね。

### Plugins
読み込み時の変換にローダーを使う一方で、
プラグインはその前後で様々なタスクを実行するようです。

※必須ではなさそうなので、ここでは省きます

## つまり
今時、モジュール化は当たり前！
それならwebpackを使おう！

依存解決のついでに、目的に応じたloaderで変換もかけちゃうぜ！