以下のリンクを合わせてお読み下さい。
Webpackとは
Webpackは、JavaScriptやその他のモジュールに依存するファイルを1つのファイルにまとめることができる便利なモジュールバンドラーです。
JavaScriptのモジュールバンドラーとしては最もよく知られており、HTMLやCSSなどのファイルに対してもバンドルすることができます。
Webpackを使用するには、Node.jsのパッケージマネージャーであるnpmを介してインストールする必要があります。
まず、"npm init"
コマンドを使用してプロジェクトを初期化し、"package.json"
ファイルを生成します。
その後、"npm install"
コマンドを使用して、Webpackで使用するためのコマンドを提供するwebpack
とwebpack-cli
パッケージをインストールします。
Webpackを構成するための4つの主要な概念として、entry
、output
、loaders
、およびplugins
があります。
これらの概念を使用して、エントリーポイントの指定、出力オブジェクトの設定、外部プラグインの追加、およびローダーの設定などを行います。これらの概念は、他のモジュールバンドラーと共通している点があります。
Webpackは、依存関係を解決し、ファイルを最適化することによって、Webアプリケーションのパフォーマンスを向上させることができます。
それは、モジュールベースの開発を促進し、コードの再利用性を高めることにも役立ちます。
Webpackは、JavaScriptのみならず、HTMLやCSSなどの他のファイルもバンドルすることができるため、Webアプリケーション開発において非常に重要な役割を果たしています。
entryとoutput
Webpackを使用してJavaScriptのモジュールをバンドルする際、エントリポイントを指定する必要があります。デフォルトの設定では、エントリポイントは通常、「src/index.js」となります。これは、HTMLファイルなども含まれます。
「webpack.config.js」ファイルで、エントリポイントを指定するために、以下のようにentryプロパティを設定します。
// webpack.config.js module.exports = { entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'my-bundle.js', } };
この例では、エントリポイントとして「./src/index.js」が指定されているため、Webpackはこのファイルをバンドルし、「my-bundle.js」という名前で出力先のdist
ディレクトリに保存します。
また、複数のエントリファイルを指定する場合、以下のように配列にして複数のファイルを指定できます。
// webpack.config.js entry: [ './src/index.js', './src/index2.js' ],
以下のoutputプロパティの一つである「output.path」では、バンドル後の出力先ディレクトリの絶対パスを指定します。
ここで使用されている__dirname
は、Node.jsが提供するグローバル変数で、現在実行中のコードのディレクトリパスを取得するために使用されます。
// webpack.config.js output: { path: path.resolve(__dirname, 'dist'), //ディレクトリの絶対パス }
また、「output.filename」プロパティでは、バンドル後のファイル名を指定できます。
通常は文字列として指定されますが、テンプレート文字列を使用することもできます。たとえば、[name]
を指定すると、エントリポイントの名前に基づいてファイル名が動的に生成されます。
// webpack.config.js output: { filename: '[name].js', //エントリポイントの名前に基づくファイル名 }
[name]
の代わりに、[contenthash]
を使用すると、バンドルされたファイルの内容に基づいた一意のハッシュがファイル名に追加されます。
これにより、ブラウザがキャッシュを更新する必要があるときにのみファイルが更新されるため、キャッシュ効率が向上します。
Loaders ローダー
Webpackは、デフォルトではJavaScriptファイルとJSONファイルのみを理解し、他のファイルはバンドルできません。これらのファイルを処理するために、Webpackはローダーを使用します。
ローダーは、JavaScript以外のソースコードを変換し、依存関係に追加する前にそれらのファイルを前処理できるようにします。
これにより、JavaScriptモジュールからCSSファイルを直接インポートすることができます。
ローダーはESコードのトランスパイルだけでなく、スタイルの処理、ESLintを使用した様々な用途にも活用できます。推奨される方法は、適用するファイルタイプを指定するためにローダーを設定することです。
これを行うには、module
プロパティにrules
配列を作成し、オブジェクト内のローダーを指定します。各ローダーには、処理対象のアセットに一致する正規表現と、変換する時に使用されるローダーを指定します。ローダーは、useプロパティに文字列や配列などで指定されます。
以下は単一のローダーを適用する例です。
// webpack.config.js module: { rules: [ { test: /\.(jpe?g|png|gif)$/, // 処理対象の拡張子を正規表現で指定 use: ['file-loader'], // ファイルを変換するために使用されるローダーを指定 }, ], },
test
は処理対象の拡張子を正規表現で指定し、変換をするファイルを指定します。
use
は変換する時に使用されるローダーを指定します。
複数のローダーを指定する場合は、以下のようにします。
module: { rules: [ //rules配列 { //設定 test: /\.(jpe?g|png|gif)$/, use: ['file-loader'], }, { //追加 test: /\.scss$/, use: [ 'style-loader', //cssをhtmlにstyleタグとして出力 'css-loader', // jsにバンドル 'sass-loader' // cssに変換、コンパイル ] } ], },
上記の例では、.scss
ファイルをstyle-loader、css-loader、sass-loaderの3つのローダーで変換しています。
style-loaderは、CSSをHTMLにstyleタグとして出力します。
css-loaderは、CSSをJavaScriptにバンドルします。
最後にsass-loaderは、CSSに変換してコンパイルします。
また、use内で使用する関数やオブジェクトを指定するには、UseEntry
プロパティを使用します。
WebpackでCSSを使用する方法については、後で説明致します。
babel-loader
Babelは、最新のECMA構文で書かれたJavaScriptコードをバニラJavaScriptにトランスパイルし、古いバージョンのブラウザなどでも動作するようにするための変換ツールです。
Babelは、JavaScriptコードをES5(古いバージョンのコード)にトランスパイルするために使用されます。
Babelを実行するには、コマンドラインに2つの主要な依存関係(モジュール)をインストールする必要があります。
それらは、「@babel/core」と「@babel/preset-env」です。
@babel/core:
Babelのコンパイラコアパッケージ
@babel/preset-env:
最新のJavaScript構文をES5に変換するためのプリセットパッケージ
これらのパッケージをインストールするには、コマンドラインから以下のコマンドを実行します。
npm install @babel/core @babel/preset-env --save-dev
これらをインストールしたら、package.json
とwebpack.config.js
の両方を調整する必要があります。
webpack.config.js
ファイルでは、Babelを使用するために、「babel-loader」と「@babel/preset-env」をローダーとして追加する必要があります。
これにより、webpackがJavaScriptファイルをロードするときに、Babelがそれらをトランスパイルして、古いバージョンのコードに変換することができます。
// webpack.config.js module.exports = { // ... 他の設定 ... module: { rules: [ { test: /\.js$/, // .jsファイルに対してローダーを適用 exclude: /node_modules/, // node_modulesディレクトリは除外する use: { loader: 'babel-loader', // Babelを使用するローダー options: { presets: ['@babel/preset-env'] // @babel/preset-envプリセットを使用 } } } ] } };
ここでは、.js
拡張子を持つJavaScriptファイルのみをBabelによって処理し、「node_modules」ディレクトリ内のファイルは除外します。
use
プロパティでは、babel-loaderを使用して、BabelがJavaScriptファイルをトランスパイルすることを指定し、options
プロパティでは、Babelが使用するプリセットを指定します。
次に、「package.json」ファイルで、Babelの設定を追加する必要があります。
以下では、「@babel/preset-env」を使用して、BabelがどのバージョンのJavaScriptに変換するかを指定します。
// package.json { "name": "my-app", "version": "1.0.0", "description": "My app", "main": "index.js", "babel": { "presets": [ "@babel/preset-env" // Babelプリセットの追加 ] }, "scripts": { "build": "webpack" }, "dependencies": { "webpack": "^5.37.1", "webpack-cli": "^4.7.2" } }
これで、Babelを使用してJavaScriptコードを古いバージョンのコードに変換する準備が整いました。
ただし、@babel/preset-env
にはtargets
オプションがあり、どのバージョンのJavaScriptを変換するかを指定できます。
例えば、IE11用にコードを変換する場合、targets
オプションに「IE 11」を指定します。
また、プロジェクトのルートディレクトリにある.babelrc
ファイルに、Babelの設定を抽出することもできます。
この方法を使用する場合、Webpackの設定ファイルからBabelの設定を削除できます。
基本的には、プロジェクトのルートディレクトリに作成し配置します。
// .babelrc { "presets": [ "@babel/preset-env" ] }
こうする事で、先程のように「package.json」および「webpack.config.js」での構成をする必要はなくなり.babelrc
ファイルに統合すると、JavaScriptソースコードを実行できるようになります。
これで、Babelを使用してJavaScriptコードを古いバージョンに変換する設定が完了しました。
これにより、新しいJavaScript構文を使用してコードを書くことができますが、すべてのブラウザで実行することができるようになります。
css-loader/style-loader
Webpackを使用してCSSを扱うためには、「css-loader」と「style-loader」という2つのローダーが必要です。
これらのローダーは、CSS、TypeScript、SCSSなどのファイルを変換し、バンドルすることができます。
まず、「css-loader」は、Webpackがアプリケーションで参照されているすべてのCSSファイルからCSSを収集し、それを文字列にまとめるためのnpmモジュールです。
次に、「style-loader」は、css-loaderによって生成された出力文字列を取得し、それを「index.html」ファイルのstyleタグ内に配置するためのローダーです。
これらのローダーをインストールするには、以下のようにターミナルで実行します。
npm install css-loader style-loader --save-dev
次に、Webpackでこれらのローダーを使用するには、「webpack.config.js」ファイルでそれらを設定する必要があります。
これには、「rule」を使用して、CSSファイルに対する処理を指定します。
例えば、以下のように設定します。
// webpack.config.js module.exports = { module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'], }, ], }, // ... };
ここで、「test」は処理対象のCSSファイルを指定し、「use」プロパティで複数のローダーを指定します。
この場合、「css-loader」が最初に適用され、出力文字列を生成し、「style-loader」がその文字列を取得して、「index.html」ファイルのstyleタグ内に配置します。
CSSファイルを直接インポートする場合、非常に簡単です。
エントリーポイントである「index.js」で、CSSファイルをインポートするだけです。
// index.js import './style.css';
/* src/style.css */ p { color: red; background-color: #000; }
これで、Webpackを使用してCSSをコンパイルし、バンドルすることができます。ただし、CSSの扱い方については、今後、個別で記事に取り上げていきます。
Plugins(プラグイン)
webpackを使用する際、プラグインを利用することで、バンドルされたコードに対してローダーが実行されるようにカスタマイズできます。
プラグインを使用するには、webpack.config.js
ファイルでプラグインを読み込むためにrequire()
を使用し、設定に追加する必要があります。
プラグインを使用するには、まずインスタンスを生成し、オプションを指定して「new」演算子を使用します。
いくつかのプラグインについて説明していきます。
• HtmlWebpackPlugin
npm install --save-dev html-webpack-plugin
HtmlWebpackPluginは、コンパイル時に、生成されたJavaScriptファイルなどが読み込まれ、表示するHTMLファイルを自動生成するプラグインです。
webpack.config.js
でrequire()
を使用してHtmlWebpackPluginを読み込みます。
// webpack.config.js const HTMLWebpackPlugin = require('html-webpack-plugin')
簡単な使用例は、作成したインスタンスをplugins配列の1つとして渡すだけです。
// webpack.config.js output: { path: path.resolve(__dirname, 'dist'), filename: '[name].js' }, plugins: [ new HTMLWebpackPlugin(), ] }
webpackを実行すると、output.path
で指定したディレクトリに「index.html」ファイルが作成されます。
また、この.html
ファイルは、[name].js
が読み込まれるように設定されています。
インスタンスを作成する際には、いくつかのオプションを渡すことができます。
// webpack.config.js new HTMLWebpackPlugin({ filename: 'default.html` })
上記では、ファイル名を指定するオプションです。
// webpack.config.js new HTMLWebpackPlugin({ filename: 'default.html`, title: 'my_blog' })
title
を指定することで、HTMLファイルの「titleタグ」内に表示されるテキストを変更できます。
また、テンプレートとして使用するファイルを指定することもできます。
• MiniCssExtractPlugin
npm install --save-dev mini-css-extarct-plugin
MiniCssExtractPluginを使用すると、CSSを別ファイルとして書き出し出力することができるプラグインです。
MiniCssExtractPluginをrequire()
を使用して読み込みます。
// webpack.config.js const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module: { rules: [ { test: /\.css$/, use: [ { loader: MiniCssExtractPlugin.loader, options: { // このオプションは、画像などの外部ファイルのパスを解決するために必要になる publicPath: '../', }, }, 'css-loader', ], }, ], }, plugins: [ new MiniCssExtractPlugin({ filename: '[name].css', }), ],
上記のように、MiniCssExtractPlugin.loaderを使うことで、CSSを別ファイルに抽出できます。
また、options
オブジェクト内にpublicPath
を指定することで、CSSから参照される外部ファイルのパスを正しく解決することができます。
MiniCssExtractPluginのコンストラクタに渡すオプションとして、「filename」を指定することで、抽出されたCSSのファイル名を指定することができます。
この例では、[name].css
と指定することで、エントリーポイントの名前と同じ名前のCSSファイルが生成されます。
これによって、CSSがJavaScriptとは別のファイルになるため、ブラウザがCSSを並列で読み込めるようになり、ページの読み込み時間を短縮することができます。
webpack-dev-server
Webpackを使ってWebアプリケーションを開発する場合、Webpack開発サーバーを使用することで簡単に開発サーバー環境を立ち上げることができます。
Webpack開発サーバーは別途インストールする必要がありますが、開発にのみ使用するため、開発依存パッケージとして--save-dev
フラグを使用してインストールします。
npm i --save-dev webpack-dev-server
Webpack開発サーバーは、即時性のあるリロードやフィードバックを提供することで、開発時間を短縮する優れたツールです。
開発サーバーは、ファイルの変更を自動的に監視し、保存時にバンドルを自動的に更新するため、開発者は手動でのビルドを心配することなく、即座に変更内容を確認できます。
Webpack開発サーバーを使用するためには、webpack構成にdevServer
プロパティを追加する必要があります。
例えば、以下のようにフォルダ指定が可能です。
// webpack.config.js module.exports = { // ...省略 devServer: { static: './dist/html', }, // ...省略 };
上記の例では、サーバーで表示するファイルとして、./dist
フォルダ内のHTMLファイルが指定されています。
もしフォルダ指定がない場合、デフォルトではpublicフォルダが使用されます。
Webpack開発サーバーを起動するためには、以下のコマンドを使用します。
npx webpack --open --mode development
このコマンドを実行することで、Webpackはデフォルトでポート8080でサーバーを起動します。
--mode
オプションは必ず指定する必要があります。
指定しない場合、エラーが発生します。
--open
オプションは、自動的にブラウザを開いてページを表示するためのオプションです。
また、--watch
オプションを使用すると、ファイルが変更されるたびにWebpackが自動的にコマンドを実行するようになります(ブラウザに反映されません)。
しかし、開発サーバーを起動する際に毎回コマンドを入力するのは面倒です。
そのため、NPM Scriptsを使用して開発サーバーを起動する方法があります。
以下のように、package.jsonファイルにscriptsフィールドを追加し、startスクリプトにwebpack-dev-server --mode development
コマンドを設定します。
// package.json { "name": "my-app", "version": "1.0.0", "scripts": { "start": "webpack-dev-server --mode development", "build": "webpack --mode production" }, "devDependencies": { "webpack": "^5.0.0", "webpack-cli": "^4.0.0", "webpack-dev-server": "^4.0.0" } }
この設定により、「npm start」コマンドを実行することで開発サーバーが起動します。
また、「npm run build」コマンドを実行することで本番環境用のバンドルファイルを生成することができます。
webpack.config.js
ファイルのdevServer
プロパティを設定することで、開発サーバーの設定を変更することができます。
以下の例では、staticプロパティに'./dist/html'
を設定しています。
これにより、開発サーバーは./dist/html
フォルダ内のファイルを表示します。
// webpack.config.js module.exports = { // ...省略 devServer: { static: './dist/html', }, };
開発サーバーを起動する際には、以下のコマンドを実行します。
npm start
上記の設定に--open
オプションを追加することで、ブラウザを自動的に開いてページを表示するようにすることができます。
また、開発中にファイルを継続的に監視し、自動的にバンドルを更新するには、--watch
オプションを使用します。
ただし、ブラウザは更新されません。
開発サーバーを停止するには、「Ctrl+C」を押します。
以上が、webpack-dev-serverを使用して開発サーバーを簡単に起動する方法となります。
最後に
Webpackは、JavaScriptアプリケーションの開発で非常に役立つツールです。Webpackは、複数のJavaScriptファイルや依存関係を結合して、1つのバンドルファイルを作成することができます。これにより、アプリケーションの読み込み時間が短縮され、パフォーマンスが向上します。
また、Webpackは、CSS、画像、フォントなどの静的ファイルもバンドルに含めることができます。これにより、アプリケーションの構築プロセスを簡素化し、保守性を向上させることができます。
Webpackは柔軟で拡張可能な性質を持っています。ローダー、プラグイン、モジュールなど、様々な機能を追加することができます。これにより、開発者は必要に応じてカスタマイズを行い、自分のプロジェクトに合わせた最適な設定を行うことができます。
Webpackの構成ファイルは、初めて使用する場合は少し複雑に見えるかもしれませんが、慣れてくると非常に便利なものとなります。最も基本的な構成ファイルは、エントリーポイントと出力先を指定することです。
これに加えて、ローダーやプラグインを追加することで、より高度な設定を行うことができます。
Webpackを使用することで、開発者は現代的なJavaScript開発に必要なスキルを身につけることができます。
Webpackが解決する問題および構成ファイルのセットアップ手順をよりよく理解できることを願っております。
本日は以上となります。
最後まで読んで頂きありがとうございました。
この記事が役に立ったら、ブックマークと共有していただけると幸いです。