以前、Webpackの使い方を学びましたが、復習がてらもう一度学びましょう。
前回のWebpack
Webpack学習の前提条件
Webpackを使用するのには、Node.jsが必要です。
私の環境だと、以下のバージョンで動作しています。
1 2 3 4 5 6 7 8 |
$ node -v v12.1.0 $ npm -v 6.12.0 $ npx -v 6.12.0 |
Webpackプロジェクトの作成
以下のディレクトリ上で作業しましょう。
1 2 |
mkdir learning-webpack cd leraning-webpack |
Webpackのインストール
Webpackをインストールします。
terminal上で以下のコマンドを実行してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# npm 初期化 npm init -y # version確認 $ npm view webpack webpack@4.41.6 | MIT | deps: 23 | versions: 639 # install npm install --save-dev webpack@4.41.6 npm view webpack-cli webpack-cli@3.3.11 | MIT | deps: 11 | versions: 95 npm install --save-dev webpack-cli@3.3.11 |
ちなみにコマンドの「–save-dev」は、ローカルの開発用の設定を意味します。
オプション名 | 内容 |
---|---|
-g | グローバルに設定(共通設定) |
–save | ローカル、かつ、公開用の設定 |
–save-dev | ローカル、かつ、開発用の設定 |
Webpackのビルド
Webpackを使って、ビルドを行いましょう。
ビルド対象のファイルを作成します。
1 2 |
mkdir src touch src/index.js |
1 2 3 4 |
// index.js console.log('build file with webpack!'); |
Webpackは、ビルド時にsrcディレクトリを見に行きます(デフォルト)。
以下のコマンドで、ビルドしましょう。
1 2 3 4 5 |
npx webpack 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/ |
ビルドが成功すると「dist」ディレクトリとその配下に「main.js」ファイルが作成されます。
1 2 |
# main.jsファイルの中身 !function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t){console.log("build file with webpack!")}]); |
ちなみに、先ほどコマンド実行した時にWARNINGが出たと思います。
実は、Webpackはmode(production or development)をオプションとして選択することが推奨されています。
1 |
npx webpack --mode development |
main.jsを確認すると以下のように見やすくなっていました。
1 2 3 4 5 6 7 8 9 10 11 |
# main.js /******/ (function(modules) { // webpackBootstrap /******/ // The module cache ... eval("// index.js\n\nconsole.log('build file with webpack!');\n\n\n//# sourceURL=webpack:///./src/index.js?"); /***/ }) /******/ }); |
引数なしだとproduction扱いになり、ファイルを圧縮することでファイルの読み込み速度を上げているっぽいですね。
本番用で使うときは、オプションを無しにするか、「production」を指定してあげると良さそうです。
Webpack -自作ファイルのビルド-
今度は、他のファイルを読み込んだ形で、Webpackの機能を試します。
1 2 |
mkdir src/modules touch src/modules/addin.js |
1 2 3 4 5 |
// addinjs export default () => { console.log('addin modules'); } |
このファイルを、indexjsから読み込みます。
1 2 3 4 5 |
// index.js import addin from './modules/addin.js'; console.log('build file with webpack!'); addin(); |
この状態でビルドします。
1 |
$ npx webpack --mode development |
main.jsを確認します。
1 2 3 4 5 |
// main.js "use strict"; eval("__webpack_require__.r(__webpack_exports__);\n// addinjs\n/* harmony default export */ __webpack_exports__[\"default\"] = (() => {\n console.log('addin modules');\n});\n\n\n//# sourceURL=webpack:///./src/modules/addin.js?"); |
問題なく取り込まれていることがわかります。Webpackはこのように依存関係のあるファイルを一纏めにしてくれる便利ツールです。
Webpack View
distフォルダ配下にindex.htmlを作成して、先ほどビルドしたmain.jsファイルを取り込んで見ましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<!-- dist/index.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Webpack View</title> </head> <body> <h1>Webpack View</h1> <script src="./main.js"></script> </body> </html> |
ブラウザを立ち上げてコンソールを確認すると、処理が動いていることがわかると思います。

Webpack – HTML/CSS設定 –
Webpackの設定方法を学びましょう。
package.jsonと同階層に以下のファイルを作成してください。
1 |
touch webpack.config.js |
ファイル名は、「webpack.config.js」である必要があります。このファイルをWebpackが自動的に選出してくれます。
Webpack – エントリポイントと出力先の指定
最初は簡単に、ファイルのエントリー先と、出力先を定義します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// webpack.config.js const path = require('path'); module.exports = { entry: './src/index.js', // エントリーファイルの指定 output: { // resolveで絶対パスを取得できる path: path.resolve(__dirname, './dist'), // 出力先 filename: 'main.js', // 任意の名前に書き換えられる } } |
出力先は、絶対パスで指定しないとwebpackコマンド実行時にエラーになりますので、ご注意ください。
尚、filenameには、特定のディレクトリ配下も指定できます。
1 2 3 4 5 6 7 8 |
// webpack.config.js module.exports = { ... output: { filename: 'js/main.js', // 任意の名前に書き換えられる } } |
これで、dist/js配下にmain.jsが生成されます。
Webpack – css-loader
css-loaderを追加してください。
1 2 3 4 5 |
$ npm view css-loader css-loader@3.5.3 | MIT | deps: 13 | versions: 105 npm install --save-dev css-loader@3.5.3 |
これは、他ファイルにインポートされたcssファイルを読み込むためのモジュールです。
Webpackの設定を追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
// webpack.config.js const path = require('path'); module.exports = { entry: './src/index.js', // エントリーファイルの指定 output: { // resolveで絶対パスを取得できる path: path.resolve(__dirname, './dist'), // 出力先 filename: 'main.js', // 任意の名前に書き換えられる }, module: { rules: [ { test: /\.css/, // testにてファイル名を検知する use: [ { loader: 'css-loader'、、 } ] } ] }, } |
上記は、moduleの中にrulesを設定し、testで検知した拡張子に対するloaderをcss-loaderにするように指定しています。
cssファイルを作成してください。
1 2 |
mkdir src/modules/css touch src/modules/css/addin.css |
1 2 3 4 5 |
/* modules/css/addin.css */ body { background-color: tomato; } |
このファイルをindex.js内で読み込みます。
1 2 3 4 5 6 7 |
// index.js // index.js import addin from './modules/addin.js'; import './modules/css/addin.css'; console.log('build file with webpack!'); addin(); |
index.jsからcssファイルを読み込むことができるので、上記でOKです。
webpackコマンドを実行します。
1 |
npx webpack --mode development |
Webpack – style-loader
先ほど、cssのモジュールを読み込めるようにしましたが、スタイルを適用させるためにはstyle-loaderが必要になります。
1 2 3 4 5 |
npm view style-loader style-loader@1.2.1 | MIT | deps: 2 | versions: 64 npm install --save-dev style-loader@1.2.1 |
webpackの設定を書き換えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// webpack.config.js const path = require('path'); module.exports = { ... module: { rules: [ { test: /\.css/, // testにてファイル名を検知する use: [ { loader: 'style-loader', // loaderは、下から適用されていくので、css-loaderより前に設定する }, { loader: 'css-loader', } ] } ] }, } |
loaderを追加しました。
注意する点としては、loaderは下から順に適用されていくので、css-loaderより上位にstyle-loaderを適用する必要があります。
webpackコマンドでビルドしましょう。
1 |
npx webpack --mode development |

OKですね。
Webpack – mini-css-extract-plugin
適用されたcssをよく見ると、HTMLの中に直接埋め込まれていました。

cssは、別ファイルを分けてインポートした方が良いです。
mini-css-extract-pluginを導入して、この問題を回避しましょう。
1 2 3 4 5 |
npm view mini-css-extract-plugin mini-css-extract-plugin@0.9.0 | MIT | deps: 4 | versions: 16 npm install --save-dev mini-css-extract-plugin@0.9.0 |
設定ファイルを書き換えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
// webpack.config.js const path = require('path'); // 1 const MiniCssExtractPlugin = require('mini-css-extract-plugin'); module.exports = { entry: './src/index.js', // エントリーファイルの指定 output: { // resolveで絶対パスを取得できる path: path.resolve(__dirname, './dist'), // 出力先 filename: 'main.js', // 任意の名前に書き換えられる }, module: { rules: [ { test: /\.css/, // testにてファイル名を検知する use: [ { // 3 loader: MiniCssExtractPlugin.loader, // loaderは、下から適用されていくので、css-loaderより前に設定する }, { loader: 'css-loader', } ] } ] }, // 2 plugins: [ new MiniCssExtractPlugin(), ], } |
ビルドします。
1 2 3 4 5 6 |
npx webpack --mode development Built at: 2020/06/04 5:25:18 Asset Size Chunks Chunk Names main.css 69 bytes main [emitted] main main.js 5.31 KiB main [emitted] main |
main.cssが生成されました。
このファイルを、dist/index.htmlから読み込みましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<!-- dist/index.html --> <!DOCTYPE html> <html> <head> <title>Webpack View</title> <link rel="stylesheet" href="./main.css"> </head> <body> <h1>Webpack View</h1> <script src="./main.js"></script> </body> </html> |

OKですね。
ちなみに、main.cssから別のファイル名にしたい場合は、設定を変更します。
1 2 3 |
new MiniCssExtractPlugin({ filename: 'addin.css' }), |
dist配下にaddin.cssが出力されるはずです。
また、特定のディレクトリ配下に格納したい場合は、以下のようにします。
1 2 3 |
new MiniCssExtractPlugin({ filename: './css/addin.css' }), |
Webpack – html-webpack-plugin
先ほど、dist/index.htmlファイルを手動で変更しましたが、html-webpack-pluginを使って自動化することができます。
1 2 3 4 5 |
npm view html-webpack-plugin html-webpack-plugin@4.3.0 | MIT | deps: 9 | versions: 97 npm install --save-dev html-webpack-plugin@4.3.0 |
Webpackの設定ファイルを書き換えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// webpack.config.js const path = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); var HtmlWebpackPlugin = require('html-webpack-plugin'); // 1 module.exports = { ... module: { ... }, plugins: [ new MiniCssExtractPlugin(), new HtmlWebpackPlugin({ template: './src/index.html' }), // 2 ], } |
srcフォルダ配下にindex.htmlを作成します。
1 |
touch src/index.html |
1 2 3 4 5 6 7 8 9 10 |
<!-- src/index.html --> <!DOCTYPE html> <html lang="en"> <head> <title>Webpack view</title> </head> <body> <h1>Webpack view</h1> </body> </html> |
ビルドをします。
1 2 3 4 5 6 |
npx webpack --mode development Asset Size Chunks Chunk Names index.html 264 bytes [emitted] main.css 69 bytes main [emitted] main main.js 5.31 KiB main [emitted] main |
index.htmlが生成されました。
dist/index.htmlのファイルの中身は以下のようになっています。
1 2 3 4 5 6 7 8 9 10 |
<!-- src/index.html --> <!DOCTYPE html> <html lang="en"> <head> <title>Webpack view</title> <link href="main.css" rel="stylesheet"></head> <body> <h1>Webpack view</h1> <script src="main.js"></script></body> </html> |
今度から、src/index.htmlを修正していけばOKです。
Webpack – ファイル構成設定 –
distの中身を整える方法を学んでいきましょう。
Webpack – clean-webpack-plugin
dist内で不要になったファイルを削除するために、clean-webpack-pluginを導入します。
1 2 3 4 5 |
npm view clean-webpack-plugin clean-webpack-plugin@3.0.0 | MIT | deps: 2 | versions: 26 npm install --save-dev clean-webpack-plugin@3.0.0 |
Webpackの設定ファイルを書き換えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// webpack.config.js ... var HtmlWebpackPlugin = require('html-webpack-plugin'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); // 1 module.exports = { ... plugins: [ new MiniCssExtractPlugin(), new HtmlWebpackPlugin({ template: './src/index.html' }), new CleanWebpackPlugin(), // 2 ], } |
distに不要のファイルを追加します。
1 |
touch dist/hoge.html |
1 2 3 4 5 6 |
tree dist dist ├── hoge.html ├── index.html ├── main.css └── main.js |
ビルドします。
1 |
npx webpack --mode development |
先ほど追加したhoge.htmlが消えたと思います。
1 2 3 4 5 |
tree dist dist ├── index.html ├── main.css └── main.js |
Webpack – srcとdistの構成を合わせる
srcとdistのファイル構成に乖離が見られるので、整理します。
srcの中身を以下のようにします。
1 2 3 4 5 6 7 8 9 |
tree src src ├── css │ └── main.css // addin.css -> main.cssに変更した ├── js │ ├── addin.js │ └── main.js // index.js -> main.jsに変更した └── templates └── index.html |
main.jsのimportを書き換えます。
1 2 3 4 5 6 7 |
// main.js import addin from '../js/addin.js'; import '../css/main.css'; console.log('build file with webpack!'); addin(); |
Webpackの設定を変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
// webpack.config.js const path = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); var HtmlWebpackPlugin = require('html-webpack-plugin'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); module.exports = { entry: './src/js/main.js', // 変更 output: { // resolveで絶対パスを取得できる path: path.resolve(__dirname, './dist'), // 出力先 filename: 'js/main.js', // 変更 }, module: { rules: [ { test: /\.css/, // testにてファイル名を検知する use: [ { loader: MiniCssExtractPlugin.loader, // loaderは、下から適用されていくので、css-loaderより前に設定する }, { loader: 'css-loader', } ] } ] }, plugins: [ new MiniCssExtractPlugin({ filename: './css/main.css' // 変更 }), new HtmlWebpackPlugin({ template: './src/templates/index.html' // 変更 }), new CleanWebpackPlugin(), ], } |
ビルドします。
1 |
npx webpack --mode development |
distのファイル構成を確認しましょう。
1 2 3 4 5 6 7 |
tree dist dist ├── css │ └── addin.css ├── index.html └── js └── main.js |
srcとdistのファイル構成が限りなく近くなりました。このようにするとメンテナンス性が上がっていい感じですね。
Webpack – 画像関連 –
Webpackの画像関連操作を学びましょう。
1 |
mkdir src/images |
上記のフォルダに読み込み用の画像ファイルを格納します。私は、demo.pngファイル(以下のファイル)を格納しておきました。

Webpack – url-loader
url-loaderを使って、画像の読み込みを行います。
1 2 3 4 5 |
npm view url-loader url-loader@4.1.0 | MIT | deps: 3 | versions: 31 npm install --save-dev url-loader@4.1.0 |
Webpackの設定を変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
module: { rules: [ { test: /\.css/, // testにてファイル名を検知する use: [ { loader: MiniCssExtractPlugin.loader, // loaderは、下から適用されていくので、css-loaderより前に設定する }, { loader: 'css-loader', } ] }, { // 追加 test: /\.png/, use: [ { loader: 'url-loader', options: { esModule: false, }, }, ], }, ], }, |
src/templates配下のindex.htmlに先ほど用意した画像を読み込む処理を記述します。
1 2 3 4 5 6 7 8 9 10 11 12 |
<!-- src/index.html --> <!DOCTYPE html> <html lang="en"> <head> <title>Webpack view</title> </head> <body> <h1>Webpack view</h1> <img src="<%= require('../images/demo.png') %>" alt=""> </body> </html> |
注意する点は、通常のimgタグの書き方と異なっている点です。
これは、loadershのtemplateの構文です。
ビルドしましょう。
1 |
npx webpack --mode development |
ブラウザを確認すると画像が読み込めていることがわかります。

Webpack – file-loader
url-loaderでは、HTMLファイルの中に直接画像情報を書き込むので、ファイルがかなり肥大化されます。
画像は別ファイルに保存される方が望ましいので、file-loaderを使ってみましょう。
1 2 3 |
npm view file-loader file-loader@6.0.0 | MIT | deps: 2 | versions: 49 npm install --save-dev file-loader@6.0.0 |
Webpackに先ほど設定したurl-loaderの設定をfile-loaderに変更します。
1 2 3 4 5 6 7 8 9 10 11 12 |
{ test: /\.png/, use: [ { loader: 'file-loader', options: { esModule: false, name: "images/demo.png", }, }, ], }, |
ビルドします。
1 |
npx webpack --mode development |
ビルドに成功したらdistフォルダを確認してください。
1 2 3 4 5 6 7 8 9 |
$ tree dist dist ├── css │ └── main.css ├── images │ └── demo.png ├── index.html └── js └── main.js |
「images/background.png」が生成されました。
ちなみに、別の拡張子、複数ファイルを扱いたい時は、以下のようにします。
1 2 3 4 5 6 7 8 9 10 11 12 |
{ test: /\.(png|jpg)/, // png, jpgを許可 use: [ { loader: 'file-loader', options: { esModule: false, name: "images/[name].[ext]" // name=ファイル名, ext=拡張子 }, }, ], }, |
その他の設定は、公式を参考にしてください。
Webpack – image-webpack-loader
image-webpack-loaderを用いて画像ファイルを圧縮しましょう。
1 2 3 4 5 |
npm view image-webpack-loader image-webpack-loader@6.0.0 | MIT | deps: 9 | versions: 38 npm install --save-dev image-webpack-loader@6.0.0 |
Webpackの設定ファイルを変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
{ test: /\.(png|jpg)/, use: [ { loader: 'file-loader', options: { esModule: false, name: "images/[name].[ext]", }, }, { loader: 'image-webpack-loader', // 追加 }, ], }, ... |
この設定を追加した状態でビルドし直すと、ファイルが圧縮されます。
Webpack – HTML生成
Webpackを使ったHTMLの効率的な生成方法について学びましょう。
Webpack – pug-html-loader / html-loader
pug-html-loader / html-loaderを使って、HTMLを効率的に作成します。
1 2 3 4 5 6 7 8 9 10 |
npm view pug-html-loader pug-html-loader@1.1.5 | MIT | deps: 2 | versions: 16 npm view html-loader html-loader@1.1.0 | MIT | deps: 5 | versions: 18 npm install --save-dev pug-html-loader@1.1.5 npm install --save-dev html-loader@1.1.0 |
Webパックの設定を変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
module: { rules: [ { test: /\.css/, // testにてファイル名を検知する ... }, { test: /\.(png|jpg)/, ... }, { test: /\.pug/, use: [ { loader: 'html-loader', }, { loader: 'pug-html-loader', options: { pretty: true, // 圧縮しないhtmlを生成する }, }, ], }, ], }, |
上記は、pug-html-loaderで最初にHTMLを処理し、次にhtml-loaderで処理を行う設定です。
次に、templatesディレクトリ配下に次のファイルを作成します。
1 |
touch src/templates/index.pug |
公式を参考に、pubを書いてみます。
1 2 3 4 5 6 7 8 9 |
<!-- src/templates/index.pug --> doctype html html(lang="en") head meta(charset="UTF-8") title Pug Practice body h1 Welcome to Pub World!!! img(src="../images/demo.png") |
Webpackの設定では、htmlを処理するようにしていたので、これをpugに変更します。
1 2 3 4 5 6 7 8 9 |
plugins: [ new MiniCssExtractPlugin({ filename: './css/main.css' }), new HtmlWebpackPlugin({ template: './src/templates/index.pug' // html -> pug }), new CleanWebpackPlugin(), ], |
ビルドします。
1 |
npx webpack --mode development |
Webpack – PUGの複数ファイル設定
pugでは複数のファイルを扱うことも可能です。
Webpackの設定を変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
plugins: [ new MiniCssExtractPlugin({ filename: './css/main.css' }), new HtmlWebpackPlugin({ template: './src/templates/index.pug', filename: 'index.html' }), new HtmlWebpackPlugin({ template: './src/templates/demo.pug', filename: 'demo.html' }), new CleanWebpackPlugin(), ], |
demo.htmlを作成します。
1 |
touch src/templates/demo.pug |
1 2 3 4 5 6 7 8 9 10 |
<!-- src/templates/demo.pug --> doctype html html(lang="en") head meta(charset="UTF-8") title demo body h1 demo page |
ビルドします。
1 |
npx webpack --mode development |

Webpack – PUGのtemplate
pugで共通している部分はtemplate化したいところです。
以下のファイルを作成してください。
1 |
touch src/templates/_menu.pug |
1 2 3 4 5 |
<!-- _menu.pug --> div a(href="./index.html") To index.html a(href="./demo.html") To demo.html |
これを、index.pugとdemo.pugに「include」を使って読み込みます。
1 2 3 4 5 6 7 8 9 10 11 |
<!-- src/templates/index.pug --> doctype html html(lang="en") head meta(charset="UTF-8") title Pug Practice body include _menu.pug h1 Welcome to Pub World!!! |
1 2 3 4 5 6 7 8 9 10 11 |
<!-- src/templates/demo.pug --> doctype html html(lang="en") head meta(charset="UTF-8") title demo body include _menu.pug h1 demo page |
ビルドします。
1 |
ブラウザを表示します。


OKですね。
Webpack – PUGの継承
Djangoのように他のpubファイルからの継承も可能です。
1 |
touch src/templates/_layout.pug |
1 2 3 4 5 6 7 8 9 10 |
<!-- src/templates/_layout.pug --> doctype html html(lang="en") head meta(charset="UTF-8") title Pug Practice body include _menu.pug block content |
index.pugを編集します。
1 2 3 |
extends _layout.pug block content h1 Welcome to Pub World!!! |
demo.pugを編集します。
1 2 3 |
extends _layout.pug block content h1 demo page |
ビルドします。
1 |
npx webpack --mode development |
Webpack – PUGと変数
PUGには、変数を設定できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<!-- src/templates/_layout.pug --> block args - var title = 'Welecome to Pug World' doctype html html(lang="en") head meta(charset="UTF-8") title #{title} body include _menu.pug block content |
「args」とつけましたが、この名前は何でも良いです。
このブロックに変数化したい要素(ここではtitle)を入れて、#{変数}にて設定を行なっています。
設定した変数は、継承先で書き換えることも可能です。
1 2 3 4 5 6 7 8 |
extends _layout.pug <!-- 継承先で同じブロックを定義するとオーバーライドされる --> block args - var title = 'Override Title' block content h1 Welcome to Pub World!!! |
Webpack – ローカルサーバー
Webpack – webpack-dev-server
webpack-dev-serverでローカルサーバーを立てて、開発を効率的に行いましょう。
1 2 3 4 5 |
npm view webpack-dev-server webpack-dev-server@3.11.0 | MIT | deps: 33 | versions: 169 npm install --save-dev webpack-dev-server@3.11.0 |
以下のコマンドで立ち上げます。
1 |
npx webpack-dev-server |
デフォルトのポートは8080番であるため、「localhost:8080」でアクセスできます。
このローカルサーバーを立ち上げている状態で、ファイルの編集を行うと自動的に変更分が画面に反映されるので便利です。
Webpack – SASS
Sassは、CSSを効率的にかけるようにしたCSSを拡張した言語です。
モダンなWebシステム開発では重宝される技術であるため、これをWebpackを用いて開発に導入してみましょう。
Webpack – node-sass / sass-loader
node-sass / sass-loaderを導入しましょう。
1 2 3 4 5 6 7 8 9 10 |
npm view sass-loader sass-loader@8.0.2 | MIT | deps: 5 | versions: 54 npm view node-sass node-sass@4.14.1 | MIT | deps: 17 | versions: 139 npm install --save-dev sass-loader@8.0.2 npm install --save-dev node-sass@4.14.1 |
node-sassは、Sass自体を取り扱い、sass-loaderはSassファイルをの拡張子ファイルをロードします。
Webpackの設定ファイルの「rules」にsassの設定を追加しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
// webpack.config.js const path = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); var HtmlWebpackPlugin = require('html-webpack-plugin'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); module.exports = { entry: './src/js/main.js', // エントリーファイルの指定 output: { // resolveで絶対パスを取得できる path: path.resolve(__dirname, './dist'), // 出力先 filename: 'js/main.js', // 任意の名前に書き換えられる }, module: { rules: [ { test: /\.(css|sass|scss)/, // sass,scssを追加 use: [ { loader: MiniCssExtractPlugin.loader, }, { loader: 'css-loader', }, { loader: 'sass-loader', // まずはsassから読み込む }, ] }, { ... }, { ... ], }, plugins: [ ... ], } |
以前説明しましたが、loaderは書き込み順序の下から読み込まれます。
src配下を確認してみましょう。
1 2 3 |
$ tree src/css/ src/css/ └── main.css |
main.cssをmain.scssに変更しましょう。
また、src/js配下のmain.jsのimportを変更します。
1 2 3 4 5 6 |
// index.js import addin from './addin.js'; import '../css/main.scss'; // css -> scssに変更 console.log('build file with webpack!'); addin(); |
ローカルサーバーを立ち上げます。
1 2 3 4 5 6 7 8 |
master *) $ npx webpack-dev-server Asset Size Chunks Chunk Names ./css/main.css 66 bytes main [emitted] main demo.html 394 bytes [emitted] index.html 401 bytes [emitted] js/main.js 363 KiB main [emitted] main |
コンパイルは成功しましたね。「localhost:8080」にアクセスしてみましょう。

OKですね。
Webpack – JavaScript(ES6)
Webpack – Babel
Babelは、JavaScriptのコンパイラです。ES6など最新のバージョンで書かれたJavaScriptをコンパイルし、古いバージョンのブラウザでも問題なくJavaScriptをできるようにしてくれます。
Babelをインストールしましょう。
1 2 3 |
npm install --save-dev babel-loader@8.0.6 npm install --save-dev @babel/core@7.9.6 npm install --save-dev @babel/preset-env@7.9.6 |
Webpackの設定ファイルの「rules」にBabelの設定を追加しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
// webpack.config.js ... module.exports = { ... }, module: { rules: [ { test: /\.js/, exclude: /node_modules/, // mode_modulesは対象外にする use: [ { loader: 'babel-loader', options: { presets: ['@babel/preset-env'], // プラグインをまとめたパッケージ }, }, ], }, { test: /\.(css|sass|scss)/, // testにてファイル名を検知する ... }, { test: /\.(png|jpg)/, ... }, { ... }, ], }, plugins: [ ... ], } |
ローカルサーバーを立ち上げます。
1 2 3 4 5 6 7 8 |
npx webpack-dev-server Asset Size Chunks Chunk Names ./css/main.css 66 bytes main [emitted] main demo.html 394 bytes [emitted] index.html 401 bytes [emitted] js/main.js 363 KiB main [emitted] main Entrypoint main = ./css/main.css js/main.js |
コンパイルも成功してますね。
Webpack – デバッグ
devtoolを用いたデバッグ方法を確認しましょう。
Webpack – JavaScriptのソースマップ
Webpackの設定に以下の設定を追加すると、JavaScriptなどデバッグしやすい形式に変換してくれるようになります。
1 2 3 4 5 6 7 |
// webpack.config.js module.exports = { devtool: 'source-map', .... } |
ローカルサーバーを立ち上げなおします。
1 |
npx webpack-dev-server |


Webpack – SASSのソースマップ
Webpackの設定ファイルにSASSのソースマップ設定を追加しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
{ test: /\.(css|sass|scss)/, // testにてファイル名を検知する use: [ { loader: MiniCssExtractPlugin.loader, // loaderは、下から適用されていくので、css-loaderより前に設定する }, { loader: 'css-loader', options: { sourceMap: true, // 追加 }, }, ... ] }, |
ローカルサーバーを立ち上げなおします。
1 |
npx webpack-dev-server |
SASSのファイルをブラウザ上で確認できるようになります。

この設定は開発の時に有効にすれば良いと思います。
Webpack – pcakage.jsonへコマンド登録
package.jsonにWebpackのコマンドを登録してみましょう。
1 2 3 4 5 6 7 |
// package.json { "scripts": { "start": "webpack-dev-server", "build": "webpack --mode production", "build-dev": "webpack --mode production" }, |
次のようにコマンドを実行します。
1 2 3 |
npm start npm run build npm run build-dev |
Webpack – React
モダンなフレームワークであるReactもWebpackを使って、開発していくことが可能です。
Webpack – preset-react
preset-reactは、reactを扱うためのパッケージのようなものです。React本体は後ほどインストールしますが、まずはpreset-reactをインストールします。
1 2 3 4 5 |
npm view @babel/preset-react @babel/preset-react@7.10.1 | MIT | deps: 7 | versions: 44 npm install --save-dev @babel/preset-react@7.10.1 |
Webpackの設定ファイルを変更しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
module: { rules: [ { test: /\.js/, exclude: /node_modules/, use: [ { loader: 'babel-loader', options: { presets: [ '@babel/preset-env', '@babel/preset-react', // 追加 ], }, }, ], }, |
以前追加したJS設定の中に、present-reactを追加してます。
ビルドしましょう。
1 |
npm run build |
Webpack – react / react-dom
react / react-domをインストールします。
1 2 3 4 5 6 7 8 |
npm view react react@16.13.1 | MIT | deps: 3 | versions: 272 npm view react-dom react-dom@16.13.1 | MIT | deps: 4 | versions: 227 npm install --save-dev react@16.13.1 npm install --save-dev react-dom@16.13.1 |
Webpack – Reactのコンポーネント
reactのコンポーネントを書いてみましょう。
1 |
touch src/js/App.jsx |
1 2 3 4 5 6 7 8 9 10 11 12 |
// src/js/App.jsx import * as React from 'react' import ReactDom from 'react-dom' const App = () => { return ( <h1>Hello React World!!!</h1> ) } export default App |
main.jsも書き換えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// main.js import React from 'react'; import ReactDOM from 'react-dom'; import App from './App.jsx'; ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById('root') ); |
また、index.pubに「div#root」を追加します。
1 2 3 4 5 6 7 8 9 |
extends _layout.pug block args - var title = 'Override Title' block content h1 Welcome to Pub World!!! div#root |
コンパイルします。
1 |
npm run build |
画面を確認してみましょう。

問題なく表示されました。
Webpack – TypeScript
最後にTypeScriptの導入方法を学びましょう。
Webpack – typescript / ts-loader
1 2 3 4 5 6 7 8 9 10 |
npm view typescript typescript@3.9.5 | Apache-2.0 | deps: none | versions: 1607 npm view ts-loader ts-loader@7.0.5 | MIT | deps: 5 | versions: 117 npm install --save-dev typescript@3.9.5 npm install --save-dev ts-loader@7.0.5 |
Webpackの設定を変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
module: { rules: [ // 追加 { test: /\.(ts|tsx)/, exclude: /node_modules/, use: [ { loader: 'ts-loader', } ] }, { |
また、TypeScriptの設定ファイルを作成します。
1 |
touch tsconfig.json |
TypeScriptの設定は、公式サイトを参考にします。
1 2 3 4 5 6 7 8 9 |
{ "compilerOptions": { "moduleResolution": "node", "module": "es6", "target": "es5", "jsx": "react", "noImplicitAny": false, } } |
src/jsディレクトリ配下にTypsScriptのファイルを作成します。
1 |
touch src/js/newTypeScript.ts |
1 2 3 4 5 6 |
// src/js/newTypeScript.ts export default (num1: number, num2: number): number => { return num1 + num2; } |
数値(number)を引数に持つ関数を定義しました。
これをmain.jsから呼び出します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// main.js import React from 'react'; import ReactDOM from 'react-dom'; import App from './App.jsx'; import add from './newTypeScript.ts'; ReactDOM.render( <React.StrictMode> <App /> <div>Sum: {add(1, 2)}</div> </React.StrictMode>, document.getElementById('root') ); |
「Sum: {add(1, 2)}」を追加しました。画面を表示してみます。

OKですね。
Webpack – @types/react
ReactをTypeScriptで書くことが可能です。
@types/reactをインストールしましょう。
1 2 3 4 5 |
npm view @types/react @types/react@16.9.35 | MIT | deps: 2 | versions: 276 npm install --save-dev @types/react@16.9.35 |
React用のファイルを作成します。
1 |
src/js/demo.tsx |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// src/js/demo.tsx import * as React from 'react' const Demo: React.FC<{ message: string}> = ({ message }) => { return ( <div> {message} </div> ) } export default Demo |
main.js内でDemoコンポーネントを読み込みます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// main.js import React from 'react'; import ReactDOM from 'react-dom'; import Demo from './demo.tsx' ReactDOM.render( <React.StrictMode> <Demo message="Hello" /> </React.StrictMode>, document.getElementById('root') ); |
ビルドしましょう。
1 |
npm run build |

OKですね。
まとめ
長くなりましたが、Webpackの使い方が何となくでも分かったのではないでしょうか。
こういった便利ツールは、積極的に取り入れて、モダンな開発環境を構築していきたいですね^^
それでは、また!
Webpack設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
// webpack.config.js const path = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); var HtmlWebpackPlugin = require('html-webpack-plugin'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); module.exports = { devtool: 'source-map', entry: './src/js/main.js', // エントリーファイルの指定 output: { // resolveで絶対パスを取得できる path: path.resolve(__dirname, './dist'), // 出力先 filename: 'js/main.js', // 任意の名前に書き換えられる }, module: { rules: [ { test: /\.(ts|tsx)/, exclude: /node_modules/, use: [ { loader: 'ts-loader', } ] }, { test: /\.js/, exclude: /node_modules/, use: [ { loader: 'babel-loader', options: { presets: [ '@babel/preset-env', '@babel/preset-react', ], }, }, ], }, { test: /\.(css|sass|scss)/, // testにてファイル名を検知する use: [ { loader: MiniCssExtractPlugin.loader, // loaderは、下から適用されていくので、css-loaderより前に設定する }, { loader: 'css-loader', options: { sourceMap: true, }, }, { loader: 'sass-loader', }, ] }, { test: /\.(png|jpg)/, use: [ { loader: 'file-loader', options: { esModule: false, name: "images/[name].[ext]", }, }, { loader: 'image-webpack-loader', }, ], }, { test: /\.pug/, use: [ { loader: 'html-loader', }, { loader: 'pug-html-loader', options: { pretty: true, }, }, ], }, ], }, plugins: [ new MiniCssExtractPlugin({ filename: './css/main.css' }), new HtmlWebpackPlugin({ template: './src/templates/index.pug', filename: 'index.html' }), new HtmlWebpackPlugin({ template: './src/templates/demo.pug', filename: 'demo.html' }), new CleanWebpackPlugin(), ], } |
package.jsonの設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
{ "name": "learning-webpack", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "webpack-dev-server", "build": "webpack --mode production", "build-dev": "webpack" }, "keywords": [], "author": "", "license": "UNLICENSED", "private": true, "dependencies": { "file-loader": "^6.0.0", "html-webpack-plugin": "^4.3.0", "sass-loader": "^8.0.2" }, "devDependencies": { "@babel/core": "^7.9.6", "@babel/preset-env": "^7.9.6", "@babel/preset-react": "^7.10.1", "@types/react": "^16.9.35", "babel-loader": "^8.0.6", "clean-webpack-plugin": "^3.0.0", "css-loader": "^3.5.3", "html-loader": "^1.1.0", "image-webpack-loader": "^6.0.0", "mini-css-extract-plugin": "^0.9.0", "node-sass": "^4.14.1", "pug-html-loader": "^1.1.5", "react": "^16.13.1", "react-dom": "^16.13.1", "style-loader": "^1.2.1", "ts-loader": "^7.0.5", "typescript": "^3.9.5", "url-loader": "^4.1.0", "webpack": "^4.41.6", "webpack-cli": "^3.3.11", "webpack-dev-server": "^3.11.0" } } |
コメントを残す
コメントを投稿するにはログインしてください。