記事内に商品プロモーションを含む場合があります
webpackでpugってどう導入するんだろう?
以上の疑問の解決記事です。
HTML → pug化のメリット
pug化のメリットは下記の通り。
- 記述が短くて済む
- include可能
- テンプレート継承が可能
それぞれについて深堀りしていきます。
① 記述が短くて済む
本記事を読み進めてもらうと分かりますが、記述が短いです。
まず、閉じタグがありません。
比較すると以下の通り。
<!-- html -->
<h1>webpackチュートリアル<span>(SCSSを追加)</span></h1>
<!-- pug -->
h1 webpackチュートリアル
span (SCSSを追加)
閉じタグの記述漏れがありません。
② include可能
各ページで、共通化可能な部分をパーツ化し、読み込むことができます。
例えば、doctype宣言・header・footerなどがそれに当たります。WordPressに詳しい方であれば、header.php・footer.phpのようなものです。
※別記事で解説してます。
③ テンプレート継承が可能
こちらも②と同様、共通部分を読み込むことができます。
②との違いは、ページ毎に変えたい箇所を変更できる点です。
例えば、「headタグ」内のtitleやdescription・keywordsなどは個別設定が必要かと思います。
②では完全共通化になりますが、テンプレート継承では個別に変更することが可能です。
他にも、pug化のメリットはありますが、これらだけでも、十分に使用価値があるでしょう。何度も同じ記述を書かなくて済むので。
※ ②③の具体的な記述については、次回解説します。
※ 本記事では①のみ。
pug-html-loader・html-loaderを使う
pug-html-loader・html-loaderをインストールする
下記コマンドでインストールします。
npm install --save-dev pug-html-loader html-loader
package.jsonを確認
正常にインストールされているか確認。
//package.json
{
"scripts": {
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"clean-webpack-plugin": "^4.0.0",
"css-loader": "^6.5.1",
"file-loader": "^6.2.0",
"html-loader": "^3.0.1", //追加
"html-webpack-plugin": "^5.5.0",
"mini-css-extract-plugin": "^2.4.5",
"node-sass": "^7.0.1",
"pug-html-loader": "^1.1.5", //追加
"sass-loader": "^12.4.0",
"style-loader": "^3.3.1",
"webpack": "^5.65.0",
"webpack-cli": "^4.9.1"
}
}
webpack-config.jsに設定を追加する
インストールに成功したら、configファイルに下記設定を追加します。
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
entry: './src/js/index.js',
output: {
path: `${__dirname}/dist`,
filename: './js/bundle.js'
},
mode: 'development',
module: {
rules: [
{
test: /\.(css|sass|scss)/,
use: [
{
loader: MiniCssExtractPlugin.loader
},
{
loader: 'css-loader'
},
{
loader: 'sass-loader'
}
]
},
{
test: /\.(png|jpg|gif|svg)/,
use: [
{
loader: 'file-loader',
options: {
name: 'images/[name].[ext]'
}
}
]
},
//ここから追加
{
test: /\.pug/,
use: [
{
loader: 'html-loader'
},
{
loader: 'pug-html-loader',
//コード成形オプション(これがないとminファイルのようになる)
options: {
pretty: true
}
}
]
}
//ここまで追加
]
},
plugins: [
new MiniCssExtractPlugin({
filename: './css/style.css'
}),
new HtmlWebpackPlugin({
//ここから変更
template: './src/templates/index.pug'
//ここまで変更
}),
new CleanWebpackPlugin()
]
}
- loaderは下から読み込まれていくので順番注意
- optionsを追加して読みやすくするとgood
src/配下にpugファイルを新規作成する
設定追加後、生成元になるsrc/配下にpugを新規作成します。
webpack-tutorial
├dist/
| ├──css/
| | └──style.css
| ├──js/
| | └──bundle.js
| └──index.html
|
├node_modules/
├src/
| ├──images/
| ├──js/
| | ├──index.js
| | └──sub.js
| ├──scss/
| | └──style.scss
| └──templates/
| | ├──index.pug //新規追加
| └──index.html
|
├package-lock.json
├package.json
└webpack.config.js
既存のindex.htmlに倣って、pugで書くと以下のようになります。
doctype html
html(lang="en")
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
body
h1 webpackチュートリアル
span (SCSSを追加)
img(src="/src/images/mountain.jpg", alt="")
img(src="/src/images/sea.jpg", alt="")
- pugのdoctype宣言は、HTML同様「! + tab」のショートカットキーが使える
webpackを起動する
下記コマンドでwebpackを起動します。
npm run build
ブラウザで確認する
ブラウザで確認すると・・・
画像が表示されていない。。。
ソースコードを見ると・・・
読み込んでいる画像ファイルが乱数になっているようです。
html-loaderバージョンを下げると正常読み込みされた
原因を探って試行錯誤を繰り返すと、原因はhtml-loaderのバージョンにあるようでした。
pugとhtml-loaderバージョンの相性が良くなかったようで、以下のように変更したら表示されました。
【変更前】3.0.1
【変更後】0.5.5
変更手順
一度パッケージをアンインストール後、再度バージョン指定をしてインストールします。
npm uninstall html-loader
npm install --save-dev html-loader@0.5.5
webpack起動後、再度ブラウザで確認
再びwebpackを起動します。
npm run build
そしてブラウザを確認すると・・・
画像が表示されました。
当然ソースコードも、従来のファイル名で読み込まれています。
【おまけ】複数ページを作成する場合
通常webサイトは複数ページ存在するものなので、ページ追加の方法も見ていきます。
やり方は、下記の通り。
- webpack-comfig.jsに記述を追加
- pugファイルを新規追加
- webpackを起動後、ブラウザで確認する
①②まで終えたら、③はここまで説明した通りなので簡単にお伝えしますね。
webpack-config.jsに記述を追加
webpack-config.jsに設定を追加しましょう。
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
entry: './src/js/index.js',
output: {
path: `${__dirname}/dist`,
filename: './js/bundle.js'
},
mode: 'development',
module: {
rules: [
{
test: /\.(css|sass|scss)/,
use: [
{
loader: MiniCssExtractPlugin.loader
},
{
loader: 'css-loader'
},
{
loader: 'sass-loader'
}
]
},
{
test: /\.(png|jpg|gif|svg)/,
use: [
{
loader: 'file-loader',
options: {
name: 'images/[name].[ext]'
}
}
]
},
{
test: /\.pug/,
use: [
{
loader: 'html-loader'
},
{
loader: 'pug-html-loader',
options: {
pretty: true
}
}
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: './css/style.css'
}),
new HtmlWebpackPlugin({
template: './src/templates/index.pug',
//ここから変更
filename: 'index.html'
//ここまで変更
}),
//ここから追加
new HtmlWebpackPlugin({
template: './src/templates/menu.pug',
filename: 'menu.html'
}),
//ここまで追加
new CleanWebpackPlugin()
]
}
※今回追加した記述がない場合、webpackがどんなファイル名にして良いか分からず、下記エラーが生じます。
ERROR in Conflict: Multiple assets emit different content to the same filename index.html
「index.htmlの同じファイル名で複数のコンテンツが出力されているよ。」
したがって、今回追加したように、テンプレート名とファイル名を追記すればOK。
pugファイルを新規追加
次にpugファイルを追加しましょう。
以下のような、階層構造になります。
webpack-tutorial
├dist/
| ├──css/
| | └──style.css
| ├──js/
| | └──bundle.js
| └──index.html
|
├node_modules/
├src/
| ├──images/
| ├──js/
| | ├──index.js
| | └──sub.js
| ├──scss/
| | └──style.scss
| └──templates/
| | ├──index.pug
| ├──index.html
| | └──menu.pug //新規追加(一例としてmenuにしてます)
|
├package-lock.json
├package.json
└webpack.config.js
以下は、追加するmenu.pugファイルの中身です。
(index.pugから少し変更してます)
doctype html
html(lang="en")
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 メニュー | webpackチュートリアル
body
h1 メニュー
span (SCSSを追加)
img(src="/src/images/mountain.jpg", alt="")
img(src="/src/images/sea.jpg", alt="")
webpackを起動後、ブラウザで確認する
ここまでできたら、再度webpackを起動し、ブラウザで確認しましょう。
npm run build
URLもindex.html → menu.html変わるので注意です。
無事に表示されました!
まとめ
本記事では、「pugを使って、効率的にコーディングしよう」と題して、以下のことを解説しました。
- HTML → pug化のメリット
- pug-html-loader・html-loaderを使う
- webpack-config.jsに設定を追加する
- src/配下にpugファイルを新規作成する
- webpackを起動する
- ブラウザで確認する
- html-loaderバージョンを下げると正常読み込みされた
- webpack起動後、再度ブラウザで確認
- 【おまけ】複数ページを作成する場合
アクシデントはありましたが、無事にpug化することができました。また、複数ページでのpug化にも成功しています。
次回は、冒頭でお伝えしたincludeやテンプレート継承について、どのように記述するかを見ていきましょう。