‍🦔 【webpack】pugを使って、効率的にコーディングする【pug-html-loader】
作成日: 2022/01/04
2

pug-html-loader・html-loaderを使う

npm install --save-dev pug-html-loader html-loader

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に設置を追加する

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を追加すること

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="")

webpackを起動する

npm run build

ブラウザで確認する

画像が表示されない・・・

生成されたdist/index.htmlを見てみると、画像ファイルが乱数になっていた。

<img src="e81bf66bfa3c13e14be1.jpg" alt="">

これだと表示されなくて当然・・・
【仮説】画像を指定したファイル名で生成されるようにすればよい。

html-loaderのバージョンを下げると正常に読み込まれた

pugとhtml-loaderバージョンの相性が良くなかったようで、試行錯誤の結果、以下のように変更したら表示された。
html-loaderのバージョン
変更前 3.0.1
変更後 0.5.5

変更手順

npm uninstall html-loader
npm install --save-dev html-loader@0.5.5

再度ブラウザで確認

表示確認OK

【おまけ】複数ページを作成する場合

通常webサイトは複数ページ存在する。

  • webpack-config.jsに記述を追加
  • pugファイルを新規追加
  • webpackを起動する
  • ブラウザ確認

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()
    ]
}

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 //新規追加
|
├package-lock.json
├package.json
└webpack.config.js

以下のようにmenu.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起動(build)後、ブラウザ確認する


事業会社にてコーダーをしています。制作は6年目。 インプットしたことをアウトプットしています。