Webpack の概要と目的
Webpack は現代のフロントエンド開発において標準的なモジュールバンドラーです。主な役割は、TypeScript や CoffeeScript といったスクリプト言語、あるいは Sass や Less などのスタイルシートを、ブラウザが解釈可能な JavaScript や CSS へ変換し、複数のファイルを単一または複数のバンドルに統合することです。
Grunt や Gulp といったタスクランナーとの違いについて疑問を持つ場合があります。これらは画像の圧縮や lint 检查など多様なタスクをパイプラインで処理するツールですが、Webpack はモジュールの依存関係解決とバンドルに特化しています。近年のフロントエンドエコシステムでは、モジュール管理の観点から Webpack の採用が一般的であり、効率的な開発環境構築に不可欠です。
基本的な設定
プロジェクト内で Webpack を使用するには、まずパッケージのインストールが必要です。グローバルインストールに加え、プロジェクトローカルにも保存することを推奨します。
npm install --save-dev webpack webpack-cli
プロジェクトのルート、あるいは設定専用のディレクトリに webpack.config.js を作成します。最も基本的な設定は、エントリーポイントと出力先の定義です。
const path = require('path');
module.exports = {
entry: './src/main.js',
output: {
filename: 'app.js',
path: path.resolve(__dirname, 'dist')
}
};
この設定により、src/main.js を起点として依存モジュールを辿り、dist/app.js として出力されます。エントリーポイントは配列で指定することで複数定義することも可能です。
開発効率化の設定
ファイル変更のたびに手動でコマンドを実行するのは非効率的です。watch オプションを使用することで、ファイルシステムの変更を検知し自動的に再ビルドできます。
module.exports = {
// ... 他の設定
watch: true
};
また、プロジェクト構造が複雑化すると、相対パスでのインポートが冗長になります。resolve.alias を使用してディレクトリに別名を付けると、コードの可読性が向上します。
resolve: {
alias: {
'@views': path.resolve(__dirname, 'src/views'),
'@utils': path.resolve(__dirname, 'src/utils')
}
}
これにより、../../src/views/header.js といったパスを @views/header.js と簡潔に記述できます。
設定ファイルがルートにない場合、context オプションでベースディレクトリを指定するか、コマンド実行時に --config フラグでパスを指定します。ビルドコマンドは package.json の scripts に登録して管理するのが一般的です。
{
"scripts": {
"start": "webpack --config config/webpack.config.js"
}
}
ローダーによるファイル処理
Webpack はデフォルトで JavaScript しか処理できません。CSS や画像ファイルをモジュールとして扱うには、ローダー(Loader)の設定が必要です。例えば、スタイルシートを JavaScript に埋め込む場合は style-loader と css-loader を使用します。
npm install --save-dev style-loader css-loader
設定ファイルの module.rules でファイル拡張子をマッチングさせ、適用するローダーを定義します。
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
exclude: /node_modules/
}
]
}
これにより、JavaScript 内で import './style.css' と記述すると、スタイルが自動的に適用されます。
プラグインと最適化
本番環境向けにコードを圧縮・難読化するにはプラグインを使用します。Webpack 5 では optimization 設定を通じて最小化を行うのが標準的です。
const webpack = require('webpack');
module.exports = {
// ...
optimization: {
minimize: true
}
};
これにより、出力されたバンドルファイルのサイズが削減され、ロードパフォーマンスが向上します。
開発用サーバー
ローカルでサーバーを立ち上げて開発するには、webpack-dev-server を利用します。これにより、ホットリロードや静的ファイルの提供が容易になります。
npm install --save-dev webpack-dev-server
設定ファイルに devServer オプションを追加し、静的ファイルの提供元ディレクトリを指定します。
devServer: {
static: {
directory: path.join(__dirname, 'public')
},
port: 3000,
open: true
}
スクリプトコマンドを webpack serve に変更することで、サーバーを起動同時にビルドを実行できます。
React 開発環境との統合
React 開発において Webpack は JSX や ES6 構文をブラウザ互換のコードへ変換するために Babel と連携します。必要なパッケージをインストールします。
npm install --save-dev babel-loader @babel/core @babel/preset-env @babel/preset-react
Babel の設定は .babelrc または babel.config.js で管理します。
{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}
Webpack 設定では、JavaScript および JSX ファイルに対して babel-loader を適用します。
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ['babel-loader']
}
]
最後に、React コンポーネントを作成して動作を確認します。例えば、src/components/Navigation.jsx を作成します。
import React from 'react';
export default function Navigation() {
return (
<nav>
<h1>Application Header</h1>
</nav>
);
}
エントリーポイントである src/main.js でこのコンポーネントをマウントします。
import React from 'react';
import ReactDOM from 'react-dom/client';
import Navigation from './components/Navigation';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Navigation />);
HTML ファイルに div id="root" を準備し、開発サーバーを起動することで、ブラウザ上で React アプリケーションが動作していることを確認できます。