この記事では、javascriptのモジュールバンドラであるwebpack
の環境を、手作業で構築するための手順を説明します。
対象読者
この記事の対象読者は下記のとおりです。
- webpackが何かざっくりとは理解できているが、詳細はあまり分かっていない。
- webpackを使ったことはあるが、自分で1から環境構築することはできない。
- webpackの仕組みについて、一度1から作業してみたい。
- 細かなコマンドのオプションは、googleなどで検索して自力で確認できる。
- 余計な前置きはなしで、作業内容だけ端的に書いてほしい。
yarnをインストールする
npm install -g yarn
yarnの初期化
yarn init -y
コマンドを実行すると、package.jsonができる
cat package.json
実行結果
{
"name": "my-project",
"version": "1.0.0",
"main": "index.js",
"author": "foobar <foobar@users.noreply.github.com>",
"license": "MIT"
}
webpackを使えるようにする
開発環境だけで使うので、"--dev"オプションを付ける。
yarn add webpack webpack-cli --dev
もしグローバルインストールしたい場合はgrobalオプションを付ける
yarn grobal add webpack webpack-cli --dev
webpack
パッケージをインストールすると、node_modulesディレクトリが作成されるが、これはgit管理しないのでgitignoreに足しておく
echo node_modules >> .gitignore
ファイルの雛形を作る
動作を確認するために、シンプルなhtmlとjsファイルを用意する。ファイルはsrcディレクトリに用意する。
mkdir src
touch src/index.js
touch src/index.html
- index.js
console.log('hello world');
- index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="index.js"></script>
</body>
</html>
(補足) vscodeの場合、index.htmlを開いた後に!
かhtml:5
を入力してTABキーを押せば、htmlの雛形が作成できる。雛形から作った場合は、langがenになっているのでjaに変更して、scriptタグを追加する。
バンドルファイルを作成する
この状態でwebpackコマンドを実行する
yarn run webpack
ビルドが成功するのを確認する。(ワーニングが出ているが、これは後で確認・対処する)
yarn run v1.22.17
$ my-project/node_modules/.bin/webpack
asset main.js 27 bytes [compared for emit] [minimized] (name: main)
./src/index.js 27 bytes [built] [code generated]
WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value.
Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/
webpack 5.64.0 compiled with 1 warning in 258 ms
✨ Done in 1.15s.
コマンドの実行により、distディレクトリの中にmain.js
が作成される。
ls dist
main.js
main.jsの内容は、最初に作ったsrc/index.jsと同じ内容になる。
(まだjsファイルが1つしかないので、この作業には特にメリットは見いだせない)
webpackの実行でワーニングが出ないようにする
コマンドラインの引数で--mode
を指定するとワーニングは出なくなる
yarn run webpack --mode development
yarn run v1.22.17
$ /...
asset main.js 1.21 KiB [emitted] (name: main)
./src/index.js 27 bytes [built] [code generated]
webpack 5.64.0 compiled successfully in 307 ms
✨ Done in 1.88s.
モードの指定が--mode development
だと、./dist/main.jsが開発用の出力になる。
先程書いたconsole.log()は下記のようにevalになる
- dist/main.jsの中身
eval("console.log('hello world');\n\n//# sourceURL=webpack://..././src/index.js?");
更にオプションとして--devtool inline-source-map
を指定すると、./dist/main.js 以下のような出力変わる。
- コマンド
yarn run webpack --mode development --devtool inline-source-map
- dist/main.jsの中身
/******/ (() => { // webpackBootstrap
var __webpack_exports__ = {};
/*!**********************!*\
!*** ./src/index.js ***!
\**********************/
console.log('hello world');
/******/ })()
;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2Z....
このようにオプションを変えることで出力を変えることができる。
毎回コマンドライン引数を指定するのは煩雑なので、通常はwebpack.config.js
という設定ファイルを用意する。
webpack.config.jsの作成
webpack.config.jsを作成し、以下の内容を書く (ちなみに、これはCommonJsの形式になっている)
module.exports = {
mode: 'development',
devtool: 'inline-source-map'
}
改めてyarn run webpack
を実行すると、ワーニングの表示が抑制されることが分かる。
yarn run webpack
yarn run v1.22.17
$ .../node_modules/.bin/webpack
asset main.js 527 bytes [emitted] (name: main)
./src/index.js 27 bytes [built] [code generated]
webpack 5.66.0 compiled successfully in 129 ms
✨ Done in 1.24s.
## webpack.config.jsの簡単な説明
ここで、webpack.config.jsでよく使う設定をいくつか確認する。
entryパラメータ
entry
でファイルのエントリポイントを指定できる。
デフォルトはsrc/index.js
が起点になるが、これを変更にしたいときに指定する。
module.exports = {
mode: 'development',
devtool: 'inline-source-map',
entry: './src/app.js'
}
(依存関係がない)複数のファイルを1のjsファイルにバンドルしたい場合は、entryを配列指定できる。
entry: [ './src/index.js', './src/sub.js']
エントリポイントが複数ある場合は、以下のように連想配列にすることができる。以下の場合だとindex.js
とindex2.js
の2ファイルががdist/
に出力される。
entry: {
main: './src/index.js',
sub: './src/index2.js'
}
outputパラメータ
output
でbundle後の出力先を指定できる。デフォルトはdist
が出力先となる。
出力先は絶対パスで必要する必要がある。このため、現在ディレクトリを取得するためにpathを利用すると良い。
const path = require('path');
module.exports = {
mode: 'development',
devtool: 'inline-source-map',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'public'),
}
}
filenameパラメータ
filename
で、出力後のファイル名を指定できる。
output: {
path: path.resolve(__dirname, 'public'),
filename: 'bundle.js',
}
複数のエントリポイントを持つ場合は、[name]
を使う、エントリポイントの名前で置換されるので便利。
output: {
path: path.resolve(__dirname, 'public'),
filename: '[name].bundle.js',
}