改めてwebpack事始め

プレイライフのサウナエンジニアの合原です。


最近新しいサービスのプロダクト開発で、Rails6で環境構築を進めています。
下記のような理由から、脱webpacker, 脱Sprocketsも考え、現在いろいろセッアッブ中です。

* webpackerの学習コストが割に合わない（webpack使えれば十分）
* 自分以外の人も使える状態にしたい（フロントエンド強者でも参画してほしい！）


ただ、久々にwebpack周りの設定をやり始めたら、意外と基本的なことを忘れていたので、備忘録も兼ねてwebpackとは、基本的な使い方等をまとめておきます（いきます）。（随時、加筆、修正します）



# webpackとは
言わずとしれた、モジュールバンドラー

# webpackerとは
webpackをRails環境下でモダンなフロントエンド開発をサポートしてくれるgem

# webpackerの問題点
* 学習コスト

rubyから、webpackを使えるようにしているだけのラッパー。


# Railsでは従来Asset Pipeline(Sprockets)が担当

sprockets が従来当たり前のようにあったが昨今のフロントエンドでは、webpackで、同じことが、より速く効率的にできる。


# モジュールのインストール方法
[yarnとの対応](https://classic.yarnpkg.com/en/docs/migrating-from-npm#toc-cli-commands-comparison)も一応載せておきます。
ここでは、引数によるインストールの違いを簡単にまとめておきます。

## npm install --save-dev
開発時に必要となるモジュールをインストールする場合`--save-dev`を指定する

### package.jsonで記載される場所
```json
{
 :,
 devDependencies : ... // ここに追加される
}
```

## npm install --save 
開発したモジュールの実行に必要となるモジュールをインストールする場合に`--save`を指定する

### package.jsonで記載される場所
```json
{
 :,
 Dependencies : ... // ここに追加される
}
```

# 最もベーシックなwebpack.congig.jsの設定
基本的には、エントリーポイントとなる`entry`と、バンドルしたものの出力先`output`を指定する。

```js
module.exports = {
  entry: './src/index.js', // エントリーポイント
  output: {
    path: `${_dirname}/dist`, // 出力先フォルダ
    filename: 'main.js'  // 出力されるファイル名
  }
}
```

# webpack-dev-server
開発時、webpackと連動して動作する開発サーバー。
開発時には、対象ファイルを編集して、リロードして、ブラウザで確認して...なんてやっていられないので、webpack利用時には、webpack-dev-serverをすると、このあたりを自動化できます。

## package.jsonへの設定
```json
module.exports = {
  "entry": './src/index.js', // エントリーポイント
  "output": {
    "path": `${__dirname}/dist`, // 出力先フォルダ
    "filename": 'main.js'  // 出力されるファイル名
  },
  "scripts": {
    "start": "webpack-dev-server --open", // サーバ起動時にブラウザを開くようにする
    "build": "webpack --config webpack.config.js"
  },
  :
  "devServer": {
    "contentBase": './dist' // 最低限必要な設定、コンテンツの検索先を指定する
  }
}
```

### devServer指定オプション

| プロパティ       |    値 |
|:-----------------|:------------------|
| host       |    使用するホスト（localhost） |
| port             |       ポート番号（既定は8080） |
| socket             |       使用するunixソケット（hostの代わりに利用） |
| headers            |       応答ヘッダー（ヘッダー名：値の形式） |
| https              |       httpsの有効無効 |
| open             |       起動時にブラウザを開くか |
| openPage         |       起動時にブラウザで開くページ |
| lazy             |       遅延モード（有効時はファイル変更の監視をしない） |
| compress             |       gzip圧縮 |
| quiet             |       ログ出力の無効化 |
| clientLogLevel    |      (none, error, warning, info) |
| overLay          |       コンパイルエラー時、ブラウザにオーバーラップして、エラーを表示 |
| watchOptions     |       ファイル監視オプション以下はサブオプション |
| --aggregateTimeout |   次回ビルドまでの遅延時間 |
| --ignored             |       監視除外フォルダ |
| --poll           |    ポーリング間隔（ms） |
| --info-verbosity |    監視メッセージの表示レベル（none, info, verbose） |

# 本番・開発モード
modeパラメータを使って切り替えをする

```json
module.exports = {
  "mode": "development", // 開発モード指定時
  "entry": './src/index.js', // エントリーポイント
  "output": {
    "path": `${__dirname}/dist`, // 出力先フォルダ
    "filename": 'main.js'  // 出力されるファイル名
  },
  "scripts": {
    "start": "webpack-dev-server --open", // サーバ起動時にブラウザを開くようにする
    "build": "webpack --config webpack.config.js"
  },
  :
  "devServer": {
    "contentBase": './dist' // 最低限必要な設定、コンテンツの検索先を指定する
  }
}
```

## 大雑把なdevelopmentモードの特徴
よりデバッグに適したコードを高速に生成することに重きを置いている

## 大雑把なproductionモードの特徴
不要なコードを削除し、できるだけ小さく、実行効率の良いコードを生成することに重きを置いている。


# ソースマップの生成
ソースマップとはビルド前後のコードをマッピングするためのファイル。ソースマップを使うことで、デバッグ時に、エラー箇所の特定が容易になる。
ソースマップ生成はモードによって違いがある。

## developmentモード時
ソースマップ生成あり　→ エラー箇所がわかりやすい、実行パフォーマンス△

## productionモード時
ソースマップ生成なし　→ エラー箇所がわかりにくい、実行パフォーマンス○、



## より正確なソースマップを利用するには
ソースマップの利用自体は、　modeパラメータの切り替えだけでもでも可能。
ただ、「ビルド時間が増えても、正確にエラー箇所の行番号を参照した」「精度が落ちても、ビルド時間を速くしたい」など、用途に応じて、ソースマップの品質の変更をしたい場合は、[`devtool`パラメータ](https://webpack.js.org/configuration/devtool/)を使う。

詳細については、[こちら](https://webpack.js.org/configuration/devtool/)

```json
module.exports = {
  "entry": './src/index.js', // エントリーポイント
  "output": {
    "path": `${__dirname}/dist`, // 出力先フォルダ
    "filename": 'main.js'  // 出力されるファイル名
  },
  "scripts": {
    "start": "webpack-dev-server --open", // サーバ起動時にブラウザを開くようにする
    "build": "webpack --config webpack.config.js"
  },
  "devtool": "eval-source-map" // 限りなくオリジナルソースを得られるeval-source-mapがいい、ビルド低速＆リビルド高速
  :
  "devServer": {
    "contentBase": './dist' // 最低限必要な設定、コンテンツの検索先を指定する
  }
}
```

# process.env.NODE_ENV
現在の、modeは
`process.env.NODE_ENV`で参照可能


まだまだ加筆予定‥