【webpack】【Pug】webpackのpugテンプレートコンパイル設定

静的ページで構成されるページであっても、なるべくならテンプレートエンジンを使用して作りたいものです。

今回は、Pugテンプレートについて取り上げます。
pugjs.org

Pugについては別の機会にするとして、webpackでコンパイルするための設定について記載します。

pugのテンプレートをコンパイルする

pugをコンパイルするにはいくつかのnodeライブラリを使用します

ライブラリ名 用途
pug pugテンプレートを解析するためのベースライブラリ
pug-plain-loader pug用のローダー
html-webpack-plugin htmlファイルを生成
html-webpack-pug-plugin pugファイルからhtmlに変換する

事前にライブラリをインストールしておきます。

$ npm i -D pug pug-plain-loader html-webpack-plugin html-webpack-pug-plugin

ディレクトリ構成

コンパイルして、distディレクトリに生成したファイルを追加する想定です。
viewsディレクトリにあるindex.pugdistディレクトリに生成します。

f:id:nakahashi_h:20200802035359p:plain

webpackの設定

pluginshtml-webpack-pluginインスタンスを追加します。
該当のテンプレートファイルを指定すればコンパイルした時にdistディレクトリ配下にファイルが追加されます。

const path = require('path');

const HtmlWebpackPlugin = require("html-webpack-plugin");
const HtmlWebpackPugPlugin = require("html-webpack-pug-plugin");

module.exports = {
    entry: 'src/js/index.js',
    module: {
        rules: [
            {
                test: /\.pug$/,
                use: 'pug-plain-loader'
            }
        ]
    },
    output: {
        path: path.join(__dirname, 'dist')
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: 'src/views/index.pug',
            filename: 'index.pug'
        }),
        new HtmlWebpackPugPlugin()
    ]
}

複数ファイルがある場合

前項では、1ファイルのみでしたが複数ファイルをコンパイルしたい場合があります。  

f:id:nakahashi_h:20200802035528p:plain

上記のような構成の場合は、ファイル毎のhtml-webpack-pluginのインスタンスを作成します。

module.exports = {
    plugins: [
        new HtmlWebpackPlugin({
            template: 'src/views/index.pug',
            filename: 'index.pug'
        }),
        new HtmlWebpackPlugin({
            template: 'src/views/users/index.pug',
            filename: 'users/index.pug'
        }),
        new HtmlWebpackPlugin({
            template: 'src/views/users/show.pug',
            filename: 'users/show.pug'
        }),
        new HtmlWebpackPugPlugin()
    ]
}

まとめて設定したい場合

今後管理するファイルが増えても、html-webpack-pluginを追加していく事で対応はできます。
しかし、都度設定するのは管理が面倒です。

その場合は、globで一覧を取得して、ファイル毎のhtml-webpack-pluginインスタンスを作成します。

ライブラリ名 用途
glob 対象のファイル群を一度に処理するためのライブラリ
$ npm i -D glob

webpackの設定

module.exportsでwebpackの設定をする前に、ファイル毎のhtml-webpack-pluginインスタンスを作っておきます。
作成したインスタンスは、pluginsに追加すれば前項で記載したようにhtml-webpack-pluginインスタンスを複数追加した状態になります。

const path = require('path');
const glob = require('glob');

const HtmlWebpackPlugin = require("html-webpack-plugin");
const HtmlWebpackPugPlugin = require("html-webpack-pug-plugin");

const srcDir = "./src"

/**
 * ファイル名のみ抽出する
 * @param path
 * @returns {*}
 */
const getFileName = function(path) {
    return path.replace(/\.[^/.]+$/, "")
}

// html-webpack-pluginのインスタンス作成
const templates = [];
const srcPugDir = srcDir + '/views';
glob.sync("**/*.pug", {
    ignore: "**/_*.pug",
    cwd: srcPugDir
}).map(function (file) {
    templates.push(
        new HtmlWebpackPlugin({
            template: path.resolve(srcPugDir, file),
            filename: getFileName(file) + '.html'
        })
    )
})

module.exports = {
    entry: 'src/js/index.js',
    module: {
        rules: [
            {
                test: /\.pug$/,
                use: 'pug-plain-loader'
            }
        ]
    },
    output: {
        path: path.join(__dirname, 'dist')
    },
    plugins: [
        ...templates,
        new HtmlWebpackPugPlugin()
    ]
}

Tips

配列に配列をマージする

前述したまとめて設定したい場合の説明のコードの中で、ドット3点を連続した変数(...templates)を指定しています。
これはスプレッド構文と言います。

developer.mozilla.org

この構文を使用すると、元の配列が個別の変数に展開された状態になります。
配列の要素ないで使用すると、pushを使用しなくてもまとめて配列に追加することができます。

©︎2017-2018 WebSandBag