webpack環境のPugで変数を別ファイルでも使用できるようにする

Gulpからwebpackに環境を移した際、別ファイルで定義した変数を使用できないということがあったので、その際の対応方法をメモ。

対応前

まずは対応前の各ファイルです。

package.json

{
  〜略〜
  "devDependencies": {
    "globule": "^1.3.4",
    "html-webpack-plugin": "^5.5.0",
    "pug": "^2.0.4",
    "pug-loader": "^2.4.0",
    "webpack": "^5.73.0",
    "webpack-cli": "^4.10.0"
  }
}

webpack.config.js

const path = require("path");
const globule = require('globule');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const webpackConfig = {
  entry: path.resolve(__dirname, "src", "js", "main.js"),
  output: {
    path: path.resolve(__dirname, "htdocs"),
    filename: "assets/js/main.js"
  },
  module: {
    rules: [
      {
        test: /\.pug$/,
        use: {
          loader: 'pug-loader',
          options: {
            pretty: true,
            root: path.resolve(__dirname, "src", "pug"),
          }
        }
      }
    ]
  },
  plugins: []
};

const pugPaths = globule.find({
  src: ['src/pug/**/*.pug', '!src/pug/**/_*.pug']
});
pugPaths.forEach(function(pugPath) {
  const filename = pugPath.replace('src/pug/', '').replace('.pug', '.html');
  webpackConfig.plugins.push(
    new HtmlWebpackPlugin({
      template: pugPath,
      filename,
      minify: false
    })
  )
});

module.exports = webpackConfig;

pugファイルの構成は以下のようになっています。

  • src
    • pug
      • _include
        • _config.pug
        • _head.pug
        • _layout.pug
      • index.pug

src/pug/_include/_config.pug

- var siteName = 'サイト名';
- var siteDomain = 'https://example.com';

src/pug/_include/_layout.pug

block variables
  include /_include/_config.pug
doctype html
html(lang="ja")
  head
    block head
      include /_include/_head.pug
  body
    block content

src/pug/_include/_head.pug

meta(charset="UTF-8")
meta(http-equiv="X-UA-Compatible" content="IE=edge")
meta(name="viewport" content="width=device-width, initial-scale=1.0")
meta(name="format-detection" content="telephone=no")

unless metaTitle
  - var thisPageTitle = '';
else
  - var thisPageTitle = metaTitle;

unless metaDescription
  - var thisPageDescription = '';
else
  - var thisPageDescription = metaDescription;

unless path
  - var thisPageUrl = siteDomain;
else
  - var thisPageUrl = siteDomain + path;

title #{thisPageTitle}
meta(name="description" content=thisPageDescription)

meta(property="og:site_name" content=siteName)
meta(property="og:title" content=thisPageTitle)
meta(property="og:description" content=thisPageDescription)
meta(property="og:url" content=thisPageUrl)
meta(property="og:image" content=siteDomain + '/assets/img/common/ogp.png')
meta(property="og:type" content='website')

src/pug/index.pug

extends /_include/_layout.pug

append variables
  - var metaTitle = 'トップタイトル';
  - var metaDescription = 'トップ説明文';
  - var path = '/';

block content
  p トップページ

この状態でコンパイルを行いましたが、_config.pugやindex.pugで設定した変数が_head.pugでうまく読み込めていませんでした。

<title></title>
<meta name="description" content="">
<meta property="og:site_name">
<meta property="og:title" content="">
<meta property="og:description" content="">
<meta property="og:url">
<meta property="og:image" content="undefined/assets/img/common/ogp.png">
<meta property="og:type" content="website">

対応方法

pugのオプションでglobalsを設定すればいいようです。

const path = require("path");
const globule = require('globule');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const webpackConfig = {
  entry: path.resolve(__dirname, "src", "js", "main.js"),
  output: {
    path: path.resolve(__dirname, "htdocs"),
    filename: "assets/js/main.js"
  },
  module: {
    rules: [
      {
        test: /\.pug$/,
        use: {
          loader: 'pug-loader',
          options: {
            globals: ["SITE", "PAGE"],
            pretty: true,
            root: path.resolve(__dirname, "src", "pug"),
          }
        }
      }
    ]
  },
  plugins: []
};

const pugPaths = globule.find({
  src: ['src/pug/**/*.pug', '!src/pug/**/_*.pug']
});
pugPaths.forEach(function(pugPath) {
  const filename = pugPath.replace('src/pug/', '').replace('.pug', '.html');
  webpackConfig.plugins.push(
    new HtmlWebpackPlugin({
      template: pugPath,
      filename,
      minify: false
    })
  )
});

module.exports = webpackConfig;

今回はSITE と PAGEという変数を使えるようにしました。
変数毎にglobalsに設定していくと煩雑になるため、_config.pugで設定しているサイト全体で使用する変数を「SITE」、ページ個別で設定する変数を「PAGE」にまとめる想定にしています。

次に_config.pugの設定をSITEを使った形に変更します。

- SITE = {};
- SITE.name = 'サイト名';
- SITE.domain = 'https://example.com';

index.pugも同じくPAGEを使った形に変更します。

extends /_include/_layout.pug

append variables
  - PAGE = {};
  - PAGE.metaTitle = 'トップタイトル';
  - PAGE.metaDescription = 'トップ説明文';
  - PAGE.path = '/';

block content
  p トップページ

これで変数の設定はできたので、_head.pugで読み込む変数を変更します。

meta(charset="UTF-8")
meta(http-equiv="X-UA-Compatible" content="IE=edge")
meta(name="viewport" content="width=device-width, initial-scale=1.0")
meta(name="format-detection" content="telephone=no")

unless PAGE.metaTitle
  - var thisPageTitle = '';
else
  - var thisPageTitle = PAGE.metaTitle;

unless PAGE.metaDescription
  - var thisPageDescription = '';
else
  - var thisPageDescription = PAGE.metaDescription;

unless PAGE.path
  - var thisPageUrl = SITE.domain;
else
  - var thisPageUrl = SITE.domain + PAGE.path;


title #{thisPageTitle}
meta(name="description" content=thisPageDescription)

meta(property="og:site_name" content=SITE.name)
meta(property="og:title" content=thisPageTitle)
meta(property="og:description" content=thisPageDescription)
meta(property="og:url" content=thisPageUrl)
meta(property="og:image" content=SITE.domain + '/assets/img/common/ogp.png')
meta(property="og:type" content='website')

これで再度コンパイルを試してみると、意図した通りに変数の値が出力されていました。

<title>トップタイトル</title>
<meta name="description" content="トップ説明文">
<meta property="og:site_name" content="サイト名">
<meta property="og:title" content="トップタイトル">
<meta property="og:description" content="トップ説明文">
<meta property="og:url" content="https://example.com/">
<meta property="og:image" content="https://example.com/assets/img/common/ogp.png">
<meta property="og:type" content="website">

参考サイト

このエントリーをはてなブックマークに追加

関連記事

コメントを残す

メールアドレスが公開されることはありません。
* が付いている欄は必須項目です

CAPTCHA


コメントが承認されるまで時間がかかります。

2022年11月
 12345
6789101112
13141516171819
20212223242526
27282930