Webフロントツール：「webpack」と「npm-scriptsによる個別ライブラリの実行」の比較

# １．webpack：Webフロントのバンドルを含むタスクランナープラットフォーム

## (1) 概要

　webpackは、以下の処理を実行できるオールインワンツール。

- Javascriptのビルド、バンドル。これが基本。
- プラグインの利用により、SASSのビルド、バンドル、画像の最適化、HTMLの静的ジェネレートなど。

　ただし、様々なビルドをするにはnpmで別途ライブラリをインストールし、更に、それをwebpackから利用するためのpluginもnpmでインストールしないと行けない。
　いわば、**ビルドやバンドルに特化したタスクランナー**であり、そのプラットフォームといえると思う。（バンドルタスクランナー）。

## (2) webpackのメリット

- これを導入すればWebのフロントに関するリソースのビルド、バンドル、作成、最適化が**一括で**できる。
- **副次的・事後的な効用**として、webpackを利用することで、**Webフロントですべき処理が何かを知ること**ができる。いわば、情報のindexのような役割もある。これは、webpackそのものというより、それらを取り巻く情報の効用だと思う。
- Javacriptに限らず、SASS、画像、HTMLなど異なるリソースに関するビルド、バンドル、最適化の処理を、webpackのconfigに則して記載できる。つまり、**共通のルールで異なるリソースのビルドの設定ができる**。学習がしやすい。

## (3) webpackのデメリット

 webpackはデファクトスタンダードなので、Webのフロント開発をする人は１度は経験しておくべきものであるが、設定が増えた場合に問題点も見えてくる。

- 基本はJavascriptのバンドルであり、その他のものはPluginを通して、副次的に処理をする。つまり、**JS以外の設定は、少し変則的で、Pluginクラスのコンストラクタに設定する**ことになる。例えば、SASSだけをビルドするにしても、途中経過としてJSファイルができてしまい、それを削除するプラグインを入れたりする。
- Javascript以外は、Pluginを必ず導入する必要があり、Pluginはライブラリのラッパーであることが多く、**ライブラリとPluginの２つをインストールするという手間**が発生することがある。
- Javascript以外のリソースの設定を増やしていくと、**webpack.config.jsの記載が増えて見にくくなる**。（Javascriptなので、分割して書けば見やすくはなる。）
- タスクを実行するライブラリとPluginが異なるため、webpack自体や、ラッパーのもととなるライブラリとの**バージョン不整合などで動かなくなることがある**。修正版がすぐに出ない場合、独自でPluginを記載して対応などをする必要がある。
- 便利なライブラリがあってもPluginを探す、または、作らないと行けない。(Pluginは簡単につくれるが）

 webpackに限らないが、色々な処理をしていくことで、設定ファイルが複雑になり、分けて書いたほうが分かりやすいのではと思ってくる。
　であれば、最初からPluginがラッピングしている元のライブラリを個別で管理して、npm-scriptsで実行しても良いのではないかという気もする。
　
# ２．npm-scriptsで個別のライブラリを実行

## (1) webpackの性質と問題点

　webpackは一つのリソースで完結するので便利であるが、処理することが増えてくると、**webpack.config.jsが肥大化**してくる。
　では、configを分けて記載するという方法もあるが、それであれば最初から、webpackを介さずに、個別に設定して、npm-scriptsで書けば、webpack、pluginを入れなくてもよいので、**タスクランナーのレイヤーが一つ少なくなる**。
　結局は、**webpackは、タスクランナープラットフォーム**であり、それ自体であらゆるビルド、バンドル、最適化をするわけではない。**強いて言えば、Javascriptのバンドラーという側面が強い**。（例えば、SASSの書き出し先の指定は、jsとは異なり、Pluginのコンストラクタで指定したりする。）

　もし、あらゆるビルドや最適化について、サードパーティのプラグインなども別途入れず、webpack自体が提供し、統一的で簡単な記述でビルド、最適化、バンドルを提供してくれるならとても便利だと思う。

　ただ、現状(v4）では、そうではなく**サードパーティライブラリに依存**し、Pluginの設定は個別の様式に従わないといけない。そうであれば、**個々のライブラリ管理に加えて、webpackへの適応(Pluginの導入、webpack用の設定の記載）という一手間が増えている**ようにも見える。

## (2) npm-scripts + 個別ライブラリを利用するメリット

 npm-scriptsと個別ライブラリによりビルド、バンドル、最適化を実行する場合のメリットは以下。

- **npm**はNode.jsを使う以上は**必ず存在**する。それに備わっているタスク実行の仕組みを使えば、**追加的なライブラリのインストールが減る**。（タスクランナーのレイヤーが一つ減る）
- 個別のライブラリごとに設定をすると、**webpackのPluginを介さないので、直接、設定情報だけを設定すればよく、設定ファイルが見やすい**。
- 個々のライブラリのバージョンアップは、非同期で進むが、独立して管理するので、全体が動かないということが少なくなる。**一つのライブラリの変化が他のライブラリーの実行に影響しにくい**。
- 独自でJavascriptやシェル、バッチコマンドを記載するにしても、その起動起点をnpm-scriptsに書いておくことで、起動方法が統一化される。

## (3) npm-scripts + 個別ライブラリを利用するデメリット

 webpackと比較すると、npm-scripts + 個別ライブラリにした場合、以下のデメリットが考えられる。

- 設定ファイルが分かれるため、**管理リソースが増える**。（**小さい場合、webpackの方がリソースが少ない**）。
- 設定ファイル**個別のルールや書式で記載しなければならず、学習コストが高い**。（webpackはPluginを使うにしても、全体の設定は統一的。）
- Javascript、CSS、SASS、画像などのビルド、バンドル、最適化に関する**ライブラリの情報を探すのがwebpackより集めにくい**。（webpackは、結果論として関連する情報が調べやすい）


# ３．フロントのビルドツールの選択基準

　webpackとnpm-scripts+個別ライブラリを比較して、それぞれのメリットとデメリットを記載した。
　それらを踏まえてツールを利用する際に、以下のような選択基準や導入方法が良いのではないだろうか。

- 初心者はwebpack。
- ビルド、バンドル、最適化の**処理が少ないのであればwebpack**が設定ファイルが少なく、手間も少なくて済む。
- **設定が増え、複雑になるのであれば、npm-scripts+個別ライブラリ**の方が分けて管理するので分かりやすく、変化に耐えやすい。
- **npm-scriptsを使うにしても**、どのような処理やライブラリが必要かを**webpackというキーワードで調べる**。その方が効率的に情報が集まる。
- npm-scriptsは基本ワンライナーでの設定の方が見やすいが、複数ビルドなど**追加的な処理がある場合**は、**Javascriptで間接的にライブラリを実行するファイルをつくる**。（**JavascriptAPI**というのが多くのライブラリのマニュアルに記載がある）

# 備考
 
　npm-scriptsと個別のビルドやバンドルツールを使う場合、2020年8月時点で良さそうだなと思うのが以下（他にもいろいろあるだろうが）。

## npm-scriptsを利用したライブラリの実行、監視、リロード

　以下のライブラリを入れると[webpack-dev-server](https://webpack.js.org/configuration/dev-server/)と同じ様な事ができる。

- [npm-run-all](https://www.npmjs.com/package/npm-run-all)：タスクを一括実行するライブラリ
- [watch](https://www.npmjs.com/package/watch)：リソースの変更を関ししてコマンドを実行するライブラリ。
- [Live Server](https://www.npmjs.com/package/live-server)：確認用のサーバ。ドキュメントルートのリソースに変更があれば、自動でブラウザをリロードしてくれる。
- [nodemon](https://www.npmjs.com/package/nodemon/v/2.0.2)：ファイルの変更を検知して、プログラムを再起動する。Live Serverとは違い、ライブラリ（コマンド）自体の再起動などに使える。

## ビルド

- [node-sass](https://www.npmjs.com/package/node-sass)：Sassのビルド。
- [rollup.js](https://rollupjs.org/guide/en/)：JSのビルド、バンドラー（JSのみのライブラリのバンドルなどでよく利用される）。
- [11ty](https://www.11ty.dev/)：HTMLの静的サイトジェネレーター(テンプレートはpug、nunjacksなど色々選べる）。minify、cssやjsをhtmlのタグ内に展開したりなどもできる。
- [html-minifier](https://www.npmjs.com/package/html-minifier)：HTMLを軽量化する。11ty内で、pluginとして利用する。


# 雑感

## 統一的なプラットフォームと個別の管理

　webpackに限らないが、何か統一的なプラットフォームを使うとき、小さい場合は問題なく手軽で便利。
　でも、処理すべき事が増えてくると、個別に管理している方が互いが影響した問題が起きにくい。また、統一的なプラットフォームに見られるように、依存階層が増えれば増えるほど、変化があったときの対応に時間がかかる。
　できるだけ、個別に、そして、階層をフラットにしている方が柔軟で分かりやすい。

　ただ、管理する数が増えはする。とはいえ、それは統一的なプラットフォーム内でも同じでどういった形式のものを管理するかという違いに尽きる。

　確かに、個別管理は、最初のコストはかかるけど、マイクロサービス的な個別管理の方が大規模や処理が少し変則的な場合は向いている。