webpack使ってみたいけど、どうやって使えばいいのかわからない。
本記事では、初めてwebpackを触る人に向けにwebpackの導入と最低限やっておきたい設定について解説しています。
僕は今までGulpを使っていたのですが、最近webpackを使う機会があり勉強しました。
勉強した内容のまとめになりますが、参考になることがあればと思います!
本記事の信頼性
30歳から異業種への転職をして、Shopify Experts企業で1年半ほどフルリモートで勤務していました。
現在は名古屋の自社開発企業のフロントエンドエンジニアしています。フリーランスとしても活動しています。
webpackとは?
それでは、webpackについて基本的な部分の解説をしていきます。
webpackの概要
webpackは、JavaScript、CSS、画像などのファイルをモジュールとして扱い、依存関係を解決しながら最適化されたアセットにまとめるモジュールバンドラーです。これにより、開発者はプロジェクト内のリソースを効率的に管理できます。
モジュールバンドラーとは、2つの単語で成り立っています。
モジュール
モジュールとは特定の機能の持ったひとまとまりのことです。
モジュール化(別ファイル)に分割することでコードの管理をしやすくします。
バンドラー
複数のスクリプトを1つのファイルにまとめるもの。なぜWebpackが重要なのか?
script.js
に複数の処理を書くこともできますが、処理が増えると1つのファイルに複数の処理が書かれて可読性が下がります。
// script.js
const hamburgerMenu () {
// 処理が入る
}
const fetchData () {
// 処理が入る
}
const toTop () [
// 処理が入る
}
hamburgerMenu ();
fetchData();
toTop ():
次のようにファイルを分割することでそのファイルが何をやっているのかを分かるようにします。
import { hamburgerMenu } from "./hamburgerMenu"
import { fetchData } from "./fetchData"
import { toTop } from "./toTop"
hamburgerMenu ();
fetchData();
toTop ():
export function hamburgerMenu () {
// 処理が入る
}
export function fetchData () {
// 処理が入る
}
export function toTop () {
// 処理が入る
}
また、JavaScript以外にも、SCSSコンパイルや画像の圧縮など行う事ができます。
このあと実際にインストールして動かしていきますが、基本概念を簡単に説明しておきます。
エントリーポイント
エントリーポイントとは、webpackがバンドル作成の開始点として使用するファイルです。
一般的にはアプリケーションのメインファイル (例: index.js
) がエントリーポイントになります。
webpackはエントリーポイントから始めて、依存関係のある他のファイルやモジュールを探索し、それらをまとめてバンドルします。設定ファイル (webpack.config.js
) でエントリーポイントを指定できます。
module.exports = {
entry: './src/index.js',
};
アウトプット
アウトプットは、webpackがバンドルされたファイルを出力する場所や方法を指定する設定です。
出力先のディレクトリやファイル名を設定ファイルで定義できます。一般的には “dist” ディレクトリにバンドルファイルが出力されます。
const path = require('path');
module.exports = {
//... (entryの設定)
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
};
ローダー
ローダーは、webpackがJavaScript以外のファイル(画像、CSS、Sass、TypeScriptなど)をバンドルに含める際の変換処理を行うための機能です。
ローダーを使用することで、さまざまな種類のファイルをモジュールとして扱い、アプリケーションに組み込むことができます。
設定ファイルでローダーを定義し、対象となるファイル拡張子と使用するローダーを指定します。
module.exports = {
//... (entryとoutputの設定)
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
],
},
};
プラグイン
プラグインは、webpackのビルドプロセスにカスタム動作を追加するための拡張機能です。
ローダーがファイルの変換を担当するのに対し、プラグインはより広範なタスクを実行できます。例えば、バンドルサイズの最適化、アセットの管理、環境変数の注入などが可能です。設定ファイルにインポートしたプラグインを登録し、必要なオプションを指定します。
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
//... (entry, output, loaderの設定)
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html',
inject: 'body',
}),
],
};
上記の例では、HtmlWebpackPluginを使って、バンドルされたJavaScriptファイルを含めたHTMLファイルを生成しています。
- エントリーポイント
webpackがバンドル作成の開始点 - アウトプット
出力する場所や方法を指定 - ローダー
変換処理 - プラグイン
機能を追加する拡張機能
webpackのインストールとセットアップ
webpack
を使用するには、node.js
とnpm
が必要です。
ここでは、インストール方法は割愛しますので、もしインストールしていなかったらしておいてください。
webpackのインストール
こちらが公式サイトです。公式のGetting Startedも参照しながら進めます。
まずは、ファイルを作成してエディターを開きます。
今回は、webpack-okalog
というフォルダを作成しました。
下記コマンドでwebpack
に必要なパッケージをインストールします。
npm init -y
npm install --save-dev webpack webpack-cli
ファイルを追加します。
– srcディレクトリを作成して、ディレクトリ内にindex.jsを作成
webpack-okalogo
├ package.json
├ package-lock.json
└ src
└ index.js
index.js
には適当にJavaScriptの簡単なコードを書いておきます。
今回はconsole.log
で出力する処理だけを書いておきます。
console.log("webpack!");
下記のコマンドを叩きます。
npx webpack --mode development
すると、distフォルダが作成されます。
webpack-okalogo
├ package.json
├ package-lock.json
├ dist
│ └ main.js
└ src
└ index.js
distの中身は下のようになっていると思います。
これでwebpack
を通してのバンドルが成功しました🚀
これで何が便利になるのよ…
これから便利にするための設定やパッケージを入れていきましょう!
設定ファイルの作成
ここから、webpack
を便利にするためのwebpack.config.js
に追加をしていきます。
webpack.config.js
ファイルを作成します。下記のように入力します。
const path = require("path");
module.exports = {
entry: "./src/index.js",
output: {
filename: "main.js",
path: path.resolve(__dirname, "dist"),
},
};
この時点で下記コマンドを入力しても、先程までと同じ結果を得られます。webpack
のデフォルトと同様の設定をしたためです。
npx webpack --mode development
webpack.config.js
をwebpack
が動作しているのか確認するために、filename: "main.js"
の部分をfilename: "hoge.js"
と書き換えてコマンドを叩いてみると結果が変わるのが確認できます。
設定ファイルをカスタマイズ
設定ファイルをカスタマイズしていきます。
事前にファイルだけ下記のように準備しておいてください。よくある作りのやつですね。
webpack-okalogo
├ package.json
├ package-lock.json
├ index.html
└ src
├ stylesheets
│ └ style.scss
└ javascripts
└ index.js
Sassを使えるようにする
npm install --save-dev css-loader sass-loader sass mini-css-extract-plugin
{
"name": "webpack-okalog",
// 省略
"devDependencies": {
"css-loader": "^6.7.3",
"mini-css-extract-plugin": "^2.7.5",
"sass": "^1.59.3",
"sass-loader": "^13.2.1",
"webpack": "^5.76.2",
"webpack-cli": "^5.0.1"
}
}
これで必要なパッケージはインストール出来ました。
次に、webpack.config.js
を編集します。
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: "./src/javascripts/index.js",
output: {
filename: "main.js",
path: path.resolve(__dirname, "dist"),
},
module: {
rules: [
{
test: /\.(scss|sass|css)$/i,
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: "./css/style.css",
}),
],
};
module: {
rules: [
{
test: /\.(scss|sass|css)$/i,
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
},
],
},
webpackでJavaScriptファイル以外を扱えるようにするために、ローダーを使用します。
- rules.test
該当ファイルを指定 - rules.use
使用するローダーのプロパティ
sass-loaderを使って、SassをCSSに変換する。
css-loaderを使って、CSSをJavaScriptにバンドルする。mini-css-extract
プラグインを使ってJavaScriptからスタイルシートの箇所をCSSファイルとして出力する。
それっぽいディレクトリを作成して、バンドルされるのか見ていきましょう!
stylesheets
直下のstyle.scss
で各ディレクトリを読み込みます。
@use "foundation";
@use "component";
components
ディレクトリ直下の_index.scss
ファイルで、_title.scss
と_button.scss
を読み込みます。
@use "title";
@use "button";
下記_title.scss
と_button.scss
の中身です。(中身は適当に書いてます。)
.title {
font-size: 32px;
}
.button {
color: red;
display: inline-block;
background: blue;
padding: 20px 50px;
&:hover {
opacity: 0.7;
}
}
foundations
ディレクトリのほうもそれっぽく書いておいてもらえると。
準備が出来たので、バンドルしてみます。
npx webpack --mode development
うまくいけば下記のように、dist/css/style.css
が生成されます。
あと少しだけ便利にするための設定を行います。
現状だと、検証画面で確認すると、要素の部分を確認してもstyle.css
となるので、下記のコードを追加することでソースマップが出力されるようになりデバッグが行いやすくなります。
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: "./src/javascripts/index.js",
// 追加
devtool: "source-map",
output: {
filename: "main.js",
path: path.resolve(__dirname, "dist"),
},
module: {
rules: [
{
test: /\.(scss|sass|css)$/i,
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: "./css/style.css",
}),
],
};
画像をコピーする&圧縮する
画像圧縮についてまだいいものがないので一旦distフォルダの画像をそのままsrcフォルダにコピーだけしていきます。
npm install --save-dev copy-webpack-plugin
次に、webpack.config.js
ファイルに追加します。
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
// 追加
const CopyPlugin = require("copy-webpack-plugin");
module.exports = {
// 省略
output: {
// 省略
},
plugins: [
// 省略
// 追加
new CopyPlugin({
patterns: [{ from: "src/images", to: "images" }],
}),
],
};
これで、コマンドを叩くとsrc/images
フォルダの中の画像がdist/images
フォルダに複製されます。
ローカル環境の構築
編集を加えたら、自動で画面が更新されるようにしていきます。
npm install --save-dev webpack-dev-server
デフォルトだとpublicフォルダの中身をみにいくようなので、設定を変更します。
設定を変更するために、webpack.config.js
に記述を追加します。
module.exports = {
mode: "development",
// 省略
devServer: {
static: {
// ファイルをおいてある場所によって変更してください。
// distフォルダの中にindex.htmlがある場合には(__dirname, "dist")になります。
directory: path.join(__dirname, "/"),
},
port: 8080,
},
module: {
// 省略
},
plugins: [
// 省略
],
};
ここの設定ができたら、下記コマンドを叩いてみましょう。
npx webpack serve
するとうまくいくと、下記のような文字が表示されるので、http://localhost:8080/をブラウザで立ち上げてください。
これでローカル環境が立ち上げり、変更を自動で検知してくれます。
実際に変更している様子が下記になります。
細かな設定など
このあたりもやっておくと開発体験が良くなりと思います。
スクリプトを登録する
毎回コマンドを覚えるのが大変ですよね…
なのでpackage.json
に登録しておくのがオススメです。
"scripts": {
"start": "webpack serve",
"build:dev": "webpack --mode development",
"build:pro": "webpack --mode production"
},
これを登録しておくことで、
npm webpack start
とすると開発環境が立ち上がるようになります。
まとめ
他にもReactやVue、TypeScriptを使えるようにしたりすることも出来ます。
ViteやTurbopackといったより新しいツールがどんどん出てきていますが、まだまだwebpackを使っている現場も多くあるだろうと思うし、基本的な概念はどれも同じだと思うのでまずはwebpackの理解を深めていこうかなと思います^^
webpackの学習にはこちらが参考なりましたので、紹介しておきます。