webpackを調べてみた👀

# はじめに
Reactなど今どきなフロントエンド開発を学ぶときに前提としてwebpackの知識が必要だと感じたのでUdemyと書籍でwebpackについて学んでみました

[モジュールバンドラーwebpackを1日で習得！しかもフルスクラッチでインストールからカスタマイズまでの手順を理解する](https://www.udemy.com/webpack-crash-course/)

[速習webpack 速習シリーズ](https://www.amazon.co.jp/%E9%80%9F%E7%BF%92webpack-%E9%80%9F%E7%BF%92%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E5%B1%B1%E7%94%B0%E7%A5%A5%E5%AF%9B-ebook/dp/B07CQLGGP9)

# webpackとは
* モジュールバンドラーの一つ。複数のファイルをとまとめること
* nodejs上で動作する`コマンドラインツール`
* 他には`Browserify`や`RequireJS`など。**webpackが一番利用されている**
* **webpack単体だとjsのみをバンドル**。ローダをインストールすることでスタイルシートや画像などもバンドルできるようになる



# モジュールバンドラーとは
* JavaScriptコード、CSS、画像などのファイル(モジュール)を一つのファイルにまとめる(bundle)
  - **webpackではJavaScriptファイル以外のファイルをバンドルするには**Loader機能を用いる**

# トランスコンパイラ(ローダー)
* モジュールバンドラーと一緒にトランスコンパイラを用いることでTypeSctriptなどのaltJs言語をコンパイルした上でバンドルすることも可能
* babel-loader
  - ES6以降のコードをES5に変換(トランスコンパイラ)
* sass-loader
  - SassをCSSにコンパイルする
* css-loader
  - CSSをモジュールに変換
* style-loader
  - style-loaderで変換したCSSのスタイルが記述されたstyleタグをHTMLに変換する

# ローダーとは
* JavaScript以外のファイル(CSSや画像など)をバンドルできるようにへんかんするプログラムのこと
* TypeScriptやVueコンポーネントをコンパイルしたり、画像をDataURLい変換するなどいろいろある

**画像も.cssも.jsファイルに変換されて、一つの.jsファイルが最終的に作成される**

# なぜモジュールバンドラーが必要なのか？ (複数ファイルをバンドルすることのメリット)
* 大規模な開発になる場合に複数のJavaScriptコードの依存関係が複雑になってしまうので
  - 一つのファイルにすることで**jsファイルを読み込む順番を気にしないといけない** 
* ファイルをまとめるのでリクエストの回数を減らせる
  - HTTP/1.1環境では同時接続数が制限されるので、転送効率が向上する
* 大規模開発に向いている
  - 最終的にモジュールバンドラーで依存関係を気にせずモジュールを一つにできるので、モジュール単位に**細かく分割して開発**することができる

# タスクランナーまたはビルドツールとは
* コンパイル、圧縮などのタスクを実行するためのツール。Grunt、gulpなどから webpackを使う

# プラグインとは
バンドル時に様々な処理を追加できる


# webpackのインストール
```
npm instal -D webpack webpack-cli
```

# webpackの実行
* npm webpack
  - webpack.confi.jsを参照して実行
* npx webpack --open --mode development

# モード付き実行
npx webpack --mode productionで本番環境の実行(圧縮あり)。

# その他の実行方法
package.jsonのscriptsフィールドにwebpackコマンドを追加して

```
"build": "webpack",
"dev": "webpack --mode development --watch " // オプションも配置できる
}
```
npm run buildで実行

scriptsで指定することで、プロジェクトで実行する方法を明示することができる。

# wepbpackの設定ファイル
webpack.config.js

### エントリーポイント
app.jsがA.js B.jsをインポートしていたらapp.jsがエントリーポイントになる

# 開発時の便利ツール
## webpack-dev-server
* webpackと連動する開発サーバー
* jsを変更したら自動でバンドルしてページを表示してくれる



# cssのバンドル
* css-loader
  - cssを読み取ってJavaScriptのオブジェクトとして扱えるようにする
  - import style from 'cssファイル'
* style-loader
  - css-loaderで読みとったスタイルをstyleタグに書き込む
  - document.body.classList.add('css-loaderで読み込んだクラス')


# 画像のバンドル
* url-loader
  - 画像をBase64にエンコード（変換）して直接HTMLファイルに埋め込む方法
  - HTTPリクエスト数を減らすことができる
* file-loader
  - url-loaderでHTMLに直接埋め込みすぎるとHTMLが肥大化してしまうので、一定大きさの画像は別ファイルとして切り出すようにする

例)２KB以上はimagesに切り出す

```
 22          test: /\.(jpe?g|png|gif|svg|ico)$/i,
 23          loader: 'url-loader',
 24          options: {
 25            limit: 2048,
 26            name: './images/[name].[ext]'
 27          }
```


# sassのバンドル
* sass-loader
  - SassのコードをコンパイルしてCSSに変換。css-loaderとstyle-loaderとのセットで利用する。

# Babel
* babel-loader
  - バンドル前にトランスコンパイルを挟むツール
* babel-core
  - babel本体
* babel-preset-env
  - ES2015のコードをトランスコンパイル
  - .babelrcに記述して設定を有効にする必要がある
* babel-preset-react
  - React独自のJSXをコンパイル

babel-loaderの設定
babel-loaderが.babelrcを見てコンパイルする

```json

 14      rules: [
 15        {
 16          test: /\.jsx?$/,
 17          exclude: /node_modules/,
 18          loader: "babel-loader"
 19        },
```

# プラグイン
## html-webpack-plugin
* html-loaderでJSでhtmlを利用できるようにする。
* JavaScriptを呼び出すためのトップページのhtmlを自動で用意。テンプレートを用意する.

## mini-css-extract-plugin
* CSSファイルのサイズが大きい場合にバンドルせずに別ファイルに分けたい場合に使用する

## uglifyjs-webpack-plugin
* console.logの自動削除 

## optimize-css-assets-webpack-plugin
* スタイルシートの圧縮。プロダクションモードでも圧縮されないので圧縮する

# マップファイルの作成
* バンドル後のエラーを追跡しやすいようにバンドル前後でのソースコードの対応ファイル。コンソールでエラーを確認したときに、バンドル前のファイルのソールコードの場所を教えてくれる
* webpack.config.jsにdevtoolの設定を追加




# 補足：git
* git merge --no-ff - -m 'merge branch into master'
  - ハイフンは直前のブランチ
  - masterブランチに変更がない場合に変更ブランチをそのままマスターにする(fast-forward(早送り)マージ)が--no-ffで新しくマージコミットを作成する方法。変更ブランチはそのまま残るので履歴を追いかけやすくなる
* git push origin HEAD
  - カレントブランチをリモートの同名ブランチにプッシュできる
* git diff
  - まだインデックスにaddしていないものを表示
* git diff --cached
  - インデックスとHEADとの差分

# 参考
https://ics.media/entry/17376/