Webpackを使ったJavaScript開発用環境を整える。

# 前書き
この記事ではブラウザ用のJavaScriptをES2015以上で書きたい人向けに最低限の環境をWebpack(4以上)で整えるための手順を備忘録のついでとして残しておく。
Reactやcssローダー、構文チェッカー等はない最低限の構成である。

# 環境とか
Node v9.2.1。パッケージ管理yarn v1.3.2を使う。
パッケージ管理は基本的にyarnで行い、npmは使わない。
バンドラにはWebpackを使う、Parcelはライブラリを分けるとかに不便そうだったから取り敢えず見送る。

# 下準備
## myProjectを作る。
```shell-session
$ mkdir myProject
$ cd myProject
$ yarn init
... 適当に答える ...
```
これでpackage.jsonができる。

## 必要なライブラリのインストール
```shell-session
$ yarn add -D webpack webpack-cli babel-preset-env babel-plugin-transform-builtin-extend
```
基本的にWebpackとbabelのみ
### [babel-plugin-transform-builtin-extend](https://qiita.com/putan/items/cde32e6f1430d5f76268)
現在のBabelでは組み込みオブジェクトの拡張が上手く行かないのでプラグインで拡張する必要がある。
以前結構ハマって情報が少なかったので特記しておく。
Webpackを使う場合babelの設定をWebpack.config.jsに書いてしまうと上手く動かなかったので**babelの設定は.babelrcに書く**。

## .babelrc
```json:.babelrc(json)
{
    "presets": [ "env" ],
    "plugins": [
        [ "transform-builtin-extend",
          { "globals": [ "Error", "Array" ] }
        ]
    ]
}
```
隠しファイル(`.`から始まる)で拡張子なしだが中身は(厳密な)jsonで結構、jsonまわりでエラーを出された。
エディター(私の場合はemacs)によってはjsonと解釈せずに変なフォーマットが入るので適当な名前、babel.json、で編集してリネームするのがいい~~そんなエディター捨てろ~~。

## webpack.config.js
```js:webpack.config.js
const path=require('path');

module.exports={
    entry: {
        domAPI: './src/domAPI.js'
    },
    output: {
        path: path.join(__dirname, '/js/'),
        filename: '[name].js'
    },
    module: {
        rules: [{
            test: /\.js$/,
            exclude: /node_modules/,
            use: [{
                loader: 'babel-loader',
            }]
        }]
    }
}
```
何回か書かされるがなれない...。
### entry
エントリーポイント(メインファイル)の設定。
JavaScriptでは相対ディレクトリの場合、**./から書く**。
省略するとバンドルする場合はインストールされたパッケージから探してそのソース自身からの相対ディレクトリは**探さない**。
Nodeでのrequireやimportをする場合も同様で省略すると**パスが通ったところ**から探す。
#### 【余談】C/C++との比較
Cでは`#include "hoge.h"`とすると./をつけた場合と同じく相対ディレクトリしか、`#include <hoge.h>`とすると省略した場合と同じくパスが通ってるディレクトリしか探さない。

### output
出力、entryと1対1対応ではなくentryのルールから類推する。
#### path
ディレクトリ位置、__dirnameはソースファイル(webpack.config.js)の置いてあるパスでありjsが出力ディレクトリになる。
単純な`+`でもたいがいは問題にならないがより良くは[pathモジュールを使って解決するのがいい(マルチプラットフォーム対策)](https://qiita.com/tanaka0325/items/60bebc8076289ea07917)。
#### filename
ファイル名、[name]はentryのプロパティ名を表している。多分これ以外の書き方はしないと思う。

### module
ファイルを読んでくる時の設定、ルールとしていくつか書ける。
#### test
正規表現のtest、値は正規表現でないといけない(?)。`/\.js$/`は.が特殊文字なのでエスケープ、$が文末での一致なので拡張子`.js`を表すと思う。
(ファイル一覧の配列に対するfilterのような関数が使いたい。)

#### exclude
除外するファイル名、これも正規表現なのでこの例では/node_modules/ディレクトリがバンドルの対象にならない。node_modulesにインストールされたファイルを使う際には再トランスパイルされなくなるためトランスパイル速度が早くなる。

#### use: { loader: ... }
読み込むときに使う設定、今は`*.js`を読む際に自動的にbabelでトランスパイルされる。
自分で関数を作って設定をしたりできるが使ったこともないし割愛する。

# Hello world
```shell-session
$ mkdir src
$ mkdir js
$ echo "console.log('hello world');" > src/domAPI.js
$ yarn run webpack --mode=development
```
3行目はテキストエディタで貼り付けてもいい。
これでjs/にjs/domAPI.jsが出来ているはずである。
webpack4からはモード指定が要求されるようになっているので`--mode=development`をつける、なくても走るが警告(黄色太文字)が出る。

## Script化(yarn)
毎回、打つのはしんどいのでpackage.jsonに

```json:package.json(追記)
    "scripts": {
        "dev": "yarn run webpack --mode=development",
        "pro": "yarn run webpack --mode=production"
    }
```
を追記すると`$ yarn run dev`もしくは`$ yarn run pro`でトランスパイルできる。
もしくは一行シェルスクリプトを書く方法もあるが好みだと思う。
もっと便利にしたければ、[yarn run watchでwatchifyして素早くjsをビルドできるようにする](https://qiita.com/kozo002/items/e55ad15f48616d060b76)、もあるが今回は見送る。

## gitの設定
### .gitignore
node_modules/以下にあるファイルはパッケージ管理から復元できるのでgitには登録しないそのため`.gitignore`ファイルに`/node_modules/`と書いておく。

```shell-session
$ git init
$ git add .  # ファイルを追加
$ git status # node_modules/以下が追加されていないことの確認
$ git commit -a -m 'First commit' # -a:all -m:メッセージは何でもいい
```
これで今回のファイルはgitで管理することができる。

# おわり
これで基本的なWebpackによるbabelまわりの設定とgitによる管理は終わりです。後はwebpack.config.jsのentryに追加するだけでいろんなファイルが作れます。