Webpack についてまとめました。
この記事は以下の構成になっています。
- Webpack とは
- Webpack のインストール
- webpack.config.js
- バンドル
- モード
- ローカルサーバー
- ソースマップ
- Babel の設定
- CSS の設定
Webpack とは
Webpack は、JavaScript におけるモジュールバンドラであり、複数の静的なリソース(JavaScript、CSS、画像など)をバンドルし、バンドルされたファイルを最適化するツール。
バンドルとはファイルを 1 つにまとめること。
Webpack を使う主な目的は、クライアントサイドでのウェブ開発において、複雑な依存関係を持つ複数のファイルを一つまたは少数のファイルにまとめ、最適化すること。
Webpack のインストール
Webpack をインストールするには Node.js がインストールされていることが前提。
Webpack は npm でwebpack
とwebpack-cli
のパッケージをインストールして使う。
npm i -D webpack webpack-cli
webpack
は Webpack 本体で、webpack-cli
は Webpack を CLI から使うために必要。
Webpack は開発環境で使うものなので、-D
をつける。
webpack.config.js
Webpack の設定はプロジェクトの直下にwebpack.config.js
を作成して行う。
webpack.config.js
は以下のように CommonJS 形式で記述する。
module.exports = {};
{}
の中で設定をオブジェクトのプロパティとして記述していく。
module.exports
はオブジェクトを外部から使えるようにするためにエクスポートして、Webpack が設定に基づいてビルドを制御する。
簡単に言えば、設定を記述したオブジェクトをエクスポートして Webpack が読み込めるようにしている。
バンドル
1. 設定
バンドルの設定はデフォルトでは、エントリーポイントであるsrc/index.js
を読み込んで、dist/main.js
で出力する。
そのため JavaScript をモジュールで分割しても、最終的にはsrc/index.js
で読み込んでいる必要がある。
エントリーポイントや出力先を変更したい場合はwebpack.config.js
に設定を記述する。
const path = require('path'); module.exports = { // エントリーポイント entry: './resources/app.js', // 出力先 output: { path: path.resolve(__dirname, 'public'), // 出力ファイル名 filename: 'bundle.js', }, };
2. 実行
バンドルを実行するにはnpx webpack
を実行する。
バンドルが成功するとデフォルトではdist/main.js
が作られ、すべての JavaScript のコードが書かれている。
オプションとして--watch
をつけて実行すると、変更が監視され自動で反映される。
webpack.config.js
でも設定できる。
module.exports = { watch: true };
また実行コマンドはpackage.json
のscripts
に登録できる。
{ "scripts": { "dev": "webpack", } }
モード
Webpack はproduction
、development
、none
の 3 つのモードでビルドできる。
production
コードを圧縮してビルドする本番環境用のモード。
development
は、開発時のモードで、ソースマップを有効にする。
none
はproduction
やdevelopment
の設定が適用されず、すべての最適化機能が無効になるモード。
コマンドで実行する場合は、以下のようにする。
# デフォルトではproduction npx webpack # development npx webpack --mode development
webpack.config.js
でも設定できる。
module.exports = { mode: 'development' };
ちなみに圧縮を行うかどうかはoptimization
のminimize
で設定できる。
production
モードの場合はデフォルトでminimize
がtrue
になっているので自動で圧縮される。
以下のようにfalse
にすると圧縮を行わない。
module.exports = { optimization: { minimize: false } };
ローカルサーバー
Webpack ではファイルの変更を検知して自動でビルドするローカルサーバーを構築できる。
ローカルサーバーを使えば、ビルドコマンドを手動で実行する必要がなくなる。
1. インストール
ローカルサーバーを使うにはwebpack-dev-server
のパッケージが必要。
npm i -D webpack-dev-server
2. 設定
webpack.config.js
に以下の設定を記述する。
module.exports = { devServer: { static: "dist", // 自動でブラウザを起動する open: true } };
3. 実行
package.json
のscripts
に以下のコマンドを記述する。
{ "scripts": { "start": "webpack serve" }, }
これでnpm run start
を実行するとローカルサーバーを起動できる。
ソースマップ
ソースマップはバンドルしたコードを元のコードに対応づけるためのマッピングファイル。ソースマップを生成すると、ブラウザの開発ツールでコードを確認できるようになる。
1. 設定
ソースマップを生成するにはwebpack.config.js
に以下の記述を行う。
module.exports = { devtool: 'source-map' }
2. 実行
ソースマップを設定している状態でバンドルを実行すると、拡張子が.map
というファイルが出力される。
デフォルトのmain.js
を出力する場合だと、同じディレクトリ内にmain.js.map
が出力される。
Babel
Babel は JavaScript の新しいの記法を古いブラウザでも対応できるように ES5 の記法に変換(トランスパイル)するツール。
ES6 から ES5 への変換だけでなく、JSX や TypeScript のトランスパイルも行うことができる。
Babel は単体だと手動で実行しなければならないため、Webpack に導入することでバンドルと同時にトランスパイルを実行できる。
Webpack で Babel が使われる流れ 1. は以下のようになる。
- Webpack がエントリーポイントからすべてのファイルを解析する
.js
ファイルを検出したらbabel-loader
が適用される- 設定した presets でトランスパイルを行う
- トランスパイルされたファイルを Webpack がバンドルする
設定例:ES6→ES5
1. インストール
Babel を導入するには Babel 本体である@babel/core
と、ES6 から ES5 に変換するための@babel/preset-env
と、Webpack で Babel を使うためのbabel-loader
をインストールする必要がある。
npm i -D @babel/core @babel/preset-env babel-loader
preset
は一連のプラグインをまとめたもので、@babel/preset-env
以外にも、JSX を JavaScript に変換する@babel/preset-react
や、TypeScript を JavaScript に変換する@babel/preset-typescript
などもある。
loader
は JSX や TypeScript、JavaScript 以外の CSS や画像を JavaScript に変換するプログラム。
2. 設定
webpack.config.js
に以下の内容を記述して、babel-loader
を使うように設定する。
module.exports = { module: { rules: [ { // 拡張子がjsのファイルを対象 test: /\.js$/, use: { // ローダーを指定 loader: "babel-loader", options: { presets: ["@babel/preset-env"] } } }, ], }, };
module
は Webpack がモジュール(JavaScript ファイルやその他のファイル)を解析し、変換する際のルールを定義するための設定。
rules
は特定のファイルタイプに対する処理方法を指定する。
test
は正規表現を使って、設定を適用するファイルを指定する。
use
はオブジェクトで指定することでローダーとオプションを設定している。
loader
は単一のローダーを指定する。複数のローダーを使うときはuse
を配列で指定する。
options
はローダーに渡すオプションを指定するもので、presets
で@babel/preset-env
を使うようにしている。
また、プロジェクト直下に.babelrc
またはbabel.config.json
を作成して設定を行う方法もある。
以下の記述で、ES6 から ES5 に変換するように設定する。
{ "presets": ["@babel/preset-env"] }
設定例:JSX
React で使う JSX も Babel でトランスパイルできる。
1. React の準備
JSX を使うので、React が必要。
npm i react react-dom
次にディレクトリ構成を以下のようにする。
├── node_modules ├── package-lock.json ├── package.json ├── public │ ├── index.html │ └── main.js ├── src │ ├── App.jsx │ └── index.jsx └── webpack.config.js
src/index.js
をエントリーポイントとして、public/main.js
で出力する。
src/index.js
、src/App.jsx
、public/index.html
を作成する。
App.jsx
import React from "react" export const App = () => { return ( <> <h1>React</h1> </> ) }
src/index.jsx
import React from "react" import { createRoot } from "react-dom/client" import { App } from "./App" createRoot(document.getElementById("root")).render( <React.StrictMode> <App /> </React.StrictMode> )
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>React</title> </head> <body> <!-- rootにコンポーネントをマウントする --> <div id="root"></div> <script src="./main.js"></script> </body> </html>
2. インストール
JSX をトランスパイルするには@babel/preset-react
が必要。
npm i -D @babel/preset-react
3. 設定
webpack.config.js
を以下のように記述する。
const path = require('path'); module.exports = { mode: 'development', entry: './src/index.jsx', output: { path: path.resolve(__dirname, 'public'), filename: 'main.js', }, devServer: { static: "public", open: true }, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env', '@babel/preset-react'] } } } ] }, resolve: { extensions: ['.js', '.jsx'] } };
設定例:TypeScript
Babel で TypeScript もトランスパイルできる。
1. インストール
Babel で TypeScript をトランスパイルするためには、TypeScript 本体であるtypescript
と、ts-loader
またはbabel-loader
のパッケージが必要。
ts-loader
とbabel-loader
の違いは、ts-loader
では TypeScript の公式のコンパイラである tsc を使い、tsconfig.json
を基に型チェックが行われるが、babel-loader
ではtsconfig.json
を使わず、型チェックが行われない。
2. 設定
webpack.config.js
にts-loader
の設定を記述する。
module.exports = { module: { rules: [ { // 拡張子がtsのファイルを対象 test: /\.ts$/, // ts-loaderを使う use: "ts-loader", // node_modules/を対象外にする exclude: /node_modules/, }, ], } };
.babelrc
に presets を追加する。
{ "presets": ["@babel/preset-env", "@babel/preset-typescript"] };
CSS の設定
JavaScript だけでなく CSS ファイルもバンドルすることができる。
1. インストール
CSS をバンドルするにはstyle-loader
とcss-loader
のパッケージが必要。
css-loader
は、CSS を JavaScript に変換するパッケージ。
style-loader
は、バンドルされた CSS を HTML でスタイルシートとして読み込めるようにするパッケージ。
npm i -D style-loader css-loader
2. 設定
webpack.config.js
にstyle-loader
とcss-loader
を使う設定を記述する。
module.exports = { module: { rules: [ { // 拡張子がcssのファイルを対象 test: /\.css$/, // 複数のloaderを使う use: ["style-loader", "css-loader"] } ] } }
css-loader
で CSS を JavaScript にバンドルしてから、style-loader
で HTML で読み込めるようにするため、css-loader
を先に使う必要がある。
use
では後に書いた loader が先に使われるため、css-loader
を後に書く。
3. 実行
npm run dev
でバンドルを実行する。
Sass の設定
Sass は CSS をより便利に書ける上位言語。
最終的に CSS に変換するので、Webpack で Sass を使う際は CSS の設定が行われていることが前提。
1. インストール
Webpack で Sass を使うには、sass-loader
とnode-sass
が必要。
npm i -D sass-loader node-sass
2. 設定
webpack.config.js
を以下のように記述する。
module.exports = { module: { rules: [ { test: /\.(sass|scss|css)$/i, // sass-loaderを追加 use: ["style-loader", "css-loader", "sass-loader"] } ] } }