静的ページで構成されるページであっても、なるべくならテンプレートエンジンを使用して作りたいものです。
今回は、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.pug
をdist
ディレクトリに生成します。
webpackの設定
plugins
でhtml-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ファイルのみでしたが複数ファイルをコンパイルしたい場合があります。
上記のような構成の場合は、ファイル毎の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
)を指定しています。
これはスプレッド構文と言います。
この構文を使用すると、元の配列が個別の変数に展開された状態になります。
配列の要素ないで使用すると、push
を使用しなくてもまとめて配列に追加することができます。