webpackとは
webpackとはウェブサービスに使われる複数のファイルをまとめられるツールのこと
なぜモジュールバンドラが必要なのか
複雑になっているフロントエンド開発に置いてコードを書くことと同じくらいのレベルで開発環境を構築することが大切だと考えられているからだと思います。
モジュールバンドラーがない時代
元々JSにはモジュールという概念が存在していませんでした。
そのためファイルを切り分けた時にグローバルな名前空間の汚染が問題として発生していた。
要するに別のファイルと同じ変数名を使っていた場合に上書きされて意図しない結果が帰ってくる。
そこで即時関数を使用することで、その問題を解決していましたし、タスクランナーを使用してファイルの結合を行っていました。
モジュールバンドラーが登場
Node.jsが登場したことによってブラウザ以外の環境でも動くために実行環境を提供されました。
それによりエンジニアが便利なツールをnpmを通して公開し利用されてきた。
その際もタスクランナーが使用されています。(gulpとか)
その後JSにESModuleといったモジュールの概念が登場しましたが、全てのブラウザに対応しているわけではないので、webpackなどのモジュールバンドラーを使用する必要があります。
webpackのメリット
先ほどwebpackとは複数のファイルをまとめられるツールと説明しましたが、以下のようなメリットがあります。
コンテンツの表示速度を改善できる
HTML1.1の場合は、同時接続数が限られるのでページを表示させるためには時間がかかってしまう。
複数のファイルをまとめることができるので、表示速度の改善に繋がる。
※HTML2.0の場合はこのメリットは感じられないと思います。
JSだけでなくCSSや画像もまとめることができる
JavaScriptだけでなく、CSSや画像もwebpackを通してJSファイルにまとめることができる。
コンテンツの表示速度に繋がる
モジュールを利用することができる
webpackは標準仕様のESmoduleが使えるメリットがあります。
これによって、コードの可読性が上がったり、保守性や再利用性も上がると考えられます。
個人的な意見とまとめ
結論webpackとはなんなのか
僕のようなデザイナーにとってwebpackというのはとてもわかりづらい。
それはなぜかJSの過去を知らないのも原因ですが、webpackの範囲が広すぎて本質がどこなのかいまいち分からないからだと思います。
個人的な理解としては、webpackとはファイルの依存関係を解決して1つのファイルにまとめるツールだとシンプルに理解するべきだと思います。
タスクランナーとは何が違うのか
先ほどのwebpackとはファイルの依存関係を解決して1つのファイルにまとめるツールと考えると分かりやすいと思います。
タスクランナーとは、web制作に置いて手間のかかるタスクを自動化させるもの(Sassのコンパイルや画像の圧縮など)
こう考えるとタスクランナーとwebpackの違いが分かりやすいなと思いました。
webpackでもsassのコンパイルやLinterを使った構文ができ、それを一緒に説明しているので結局何が違うの?と自分自身も疑問に感じてたので僕のような初心者に見て欲しいです。
タスクランナーからwebpackへまとまってきているのか
単純にwebpackでタスクランナーのようなScssnのコンパイルなどが実現可能だからだと思います。(以下の環境設定でもしております。)
また昨今のようなSFCでは、ブラウザで読み込ませるためにもWebpackが必要になるため、必然的にタスクランナーからwebpackへ以降してきていると思っています。
実際に環境設定を行ってみました。
// ファイルおよびディレクトリパスを操作するためにアクセスする。
const path = require('path')
module.exports = {
// エントリーポイント(mainとなるJSファイル)
entry: './src/index.js',
// ファイルの出力設定
output: {
// 出力ファイルのディレクトリ名
// path.resolveは実行したスクリプトの位置からのパスになってしまうため、__dirnameを組み合わせることでファイルからのパスに変更できる。
path: path.resolve(__dirname, './dest'),
// 出力ファイル名
filename: 'bundle.js',
},
// ローカル開発用環境を立ち上げる
// contentBaseで指定したディレクトリが、サーバの起点になります。
// open: trueにすれば自動でブラウザが立ち上がる
devServer: {
contentBase: path.resolve(__dirname, 'public')
},
// productionにすることでJSのコードが圧縮される。しかし開発の場合はdevelopmentの方がいいでしょう。
mode: 'production',
module: {
rules: [{
// 対象となるファイルの拡張子の設定
test: /\.scss/,
use: [
"style-loader",
{
// linkタグに出力する機能を設定
loader: "css-loader",
options: {
// オプションでCSS内のurl()メソッドの取り込みを禁止する
url: false,
// ソースマップを有効にするか
sourceMap: true,
// 何を利用するか。今回はscssとpostCssを利用するので2
// 0 => no loaders (default);
// 1 => postcss-loader;
// 2 => postcss-loader, sass-loader
importLoaders: 2
}
},
{
// PostCSSのための設定
loader: 'postcss-loader',
options: {
sourceMap: true,
plugins: [
// Autoprefixerを有効化
// ベンダープレフィックスを自動付与する
require('autoprefixer')({
browsers: ["last 2 versions", "ie >= 11", "Android >= 4"]
})
]
},
},
{
loader: "sass-loader",
options: {
sourceMap: true
}
},
]
}]
},
}
<html>
<head>
<meta charaset="utf-8">
<title>Vue-test</title>
<script src="bundle.js"></script>
</head>
<body>
<div class="test">
<p class="test-text">Hello World</p>
</div>
</body>
</html>
ScssとpostCssあたりがどうゆう流れなのかわかりずらいので、自分なりにまとめます。
1.scss-loaderでscssをcssに変換
2.cssをpostcss-loaderでautoprifixerを追加
3.css-loaderでcssをjsにバンドルする
4.style-loaderでタグにcssを展開する
と行った流れになってると思います。(不安)
webpackの情報はネット上に転がっているので、定石通りに進めていれば何も苦はありませんでした。
しかし、個人的な意見でもまとめたようにwebpackとは依存関係を解決してファイルを1つにまとめることが本質だと思っています。
autoprefixerやscssなどを導入するのが果たして正しいのか自分では分かりきれませんがそうゆうこともできるという学びを得ました。