owned mediaウェブ制作に役立つコンテンツを発信中!

ViteでPugのコンパイル環境を導入する

最終更新日: Update!!
HTMLのマークアップを効率よく進めていく時にとても便利なPugですが、やはりViteの環境でも使えるようにしたいですね。公式ではないものの、Pugのコンパイルに対応するプラグインがいろいろと揃っていルようですので試してみたいと思います。今回はPugファイルのコンパイルだけでなく、外部データをインポートしてページごとの固有データを管理できる例もあわせてみていきます。   今回の内容は、下記の記事でViteの基本的な開発環境ができているという前提になります。詳しくは各記事でまとめていますので合わせてご参照ください。 (参考記事) フロントエンドの開発環境にVite + TypeScriptを導入する ViteでPostCSS周りの設定やSassを使う ViteでTailwindCSSとテンプレートエンジンのHandlebarsを使ったページコーディング ViteでVue.jsとVuex(Pinia)とVue Routerを使ってみる ViteでStylelintとESlintを使える環境を構築する ViteでMarkuplintとPrettierを使える環境を構築する    
Pugコンパイル環境の構築
まずは必要なモジュールをインストールしていきます。ここでは「vite-plugin-pug」というものを使っています。このプラグインでは、HTML側で「pug」というHTML要素名で外部のPugファイルをインポートするようにする形でコンパイルしていきます。そのため、純粋なPugの使い方とすこし異なる部分もありますが、個人的にはソースファイルのHTMLをそのまま使えるところが良いと思いましたので採用することが多いですね。
$ npm install --save-dev vite-plugin-pug
  インストール後はViteのプラグインとして使っていきます。設定ファイルのプラグインに追加し、引数には各種オプションなどが指定できます。1つ目にはPugのオプションを、2つ目にはローカル環境でインポートデータを指定します。今回はローカル側に配置したJSONファイルをメタ情報などのサイトデータとしてコンパイル時にHTMLで扱えるようにしていきます。
import pug from 'vite-plugin-pug';
.....
plugins: [
  pug({ 
    オプション, 
    ローカルインポートのデータ 
  })
]
  上記の内容を実際にViteの設定ファイルに追加していきます。受け渡すデータとしては環境変数と外部ファイルとしてインポートしたサイトデータになります。以前に「ViteでHandlebarsを使った複数ページの作成に使える外部JSONファイルのデータを読み込む」の記事で紹介しているのと同じような感じですね。 【vite.config.js】
import pug from 'vite-plugin-pug';

const env = {
  url: {
    development: 'http:localhost',
    production: 'https://example.com'
  },
  siteData: require('./sitedata.json')
}

export default defineConfig(({ command }) => ({
  .....
  plugins: [
    .....
    pug({
      localImports: true // Pugのオプションが使えます(https://pugjs.org/api/reference.html#options)
    }, {
      envUrl: command === 'serve' ? env.url.development : env.url.production,
      siteName: env.siteData.siteName,
      siteUrl: env.siteData.siteUrl,
      pageMeta: env.siteData.pageMeta
    }),
  ]
}));
  Pugのコンパイル時に扱うローカルデータになるJSONファイルも用意します。こちらもHandlebarsの時に使ったものを併用しています。(参考記事:ViteでHandlebarsを使った複数ページの作成に使える外部JSONファイルのデータを読み込む) 【siteData.json】
{
  "siteName": "サンプルサイト",
  "siteUrl": "https://example.com",
  "pageMeta": {
    "/index.html": {
      "id": 1,
      "name": "home",
      "title": "トップページ",
      "description": "サイトのトップページです",
      "ogpImage": "/public/images/icon/ogp_default.jpg",
      "type": "website",
      "path": "/"
    },
    "/page1.html": {
      "id": 2,
      "name": "page1",
      "title": "ページ1|サンプルサイト",
      "description": "ページ1の説明文です",
      "ogpImage": "/public/images/icon/ogp_default.jpg",
      "type": "article",
      "path": "/page1.html"
    }
  }
}
  ソースファイル側のHTMLでPugファイルを読み込んでいきます。使い方もシンプルで、Pugの独自要素として定義したPugファイルをインクルードするような感じで記述していきます。src属性で対象となるPugファイルのパスを指定します。コンパイル時には、PugファイルからHTMLに変換されたHTML文字列が該当要素に置換されるというような仕組みのようですね。エントリーポイントになるスクリプトファイルですが、Pugのコンポーネント側で読み込むと上手くビルドできなかったので、HTML側で読み込むことがポイントです。 【src/index.html】
<!DOCTYPE html>
<html lang="ja">
  <head>
    <pug src="./pug/components/head.pug" />
    <pug src="./pug/meta/index.pug" />
  </head>
  <body>
    <pug src="./pug/components/header.pug" />
    <pug src="./pug/index.pug" />
    <pug src="./pug/components/footer.pug" />
    <script type="module" src="./main.ts"></script>
  </body>
</html>
  上記のようにHTMLへ記述する部分は通常のPugと異なる部分になりますが、読み込まれるPugファイルはいつもの記法でファイルを作成していきます。
// src/pug/components/head.pug
meta(charset='utf-8')
meta(name='viewport' content='width=device-width,initial-scale=1.0')


// src/pug/components/header.pug
header.
  ヘッダー要素


// src/pug/components/footer.pug
footer.
  フッター要素


// src/pug/index.pug
main.page-home
  h1 トップページ
  p トップページのコンテンツです
  インポートしたローカルデータを扱うページ固有となるPugファイルでは、Viteの設定ファイルで設定したキーから参照することでアクセスできるようになります。ページごとにキーを振り分けていますので、対応するページのキーを指定します。 【src/pug/meta/index.pug】
block variables 
  //- ページ固有設定用の変数
  - var page = '/index.html'

// ページ固有設定メタデータ
meta(property='og:title' content=pageMeta[page]['title'])
meta(property='og:description' content=pageMeta[page]['description'])
meta(property='og:url' content=envUrl + pageMeta[page]['path'])
meta(property='og:type' content=pageMeta[page]['type'])
meta(property='og:image' content=envUrl + pageMeta[page]['ogpImage'])
meta(name='twitter:title' content=pageMeta[page]['title'])
meta(name='twitter:description' content=pageMeta[page]['description'])
meta(name='twitter:url' content=envUrl + pageMeta[page]['path'])
meta(name='description' content=pageMeta[page]['description'])
link(rel='canonical' href=envUrl + pageMeta[page]['path'])
title !{pageMeta[page]['title']} 
script(type="application/ld+json").
  {
    "@context": "http://schema.org",
    "@type": "BreadcrumbList",
    "itemListElement": [
      { 
        "@type": "ListItem", 
        "position": 1, 
        "item": { 
          "@id": "!{envUrl}/", 
          "name": "HOME" 
        } 
      }
    ]
  }
  上記の内容でコンパイルするとこのようにローカルデータが反映された内容でPugからHTMLに変換されたファイルがビルドできました。 【dist/index.html】
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <meta property="og:title" content="トップページ" />
    <meta property="og:description" content="サイトのトップページです" />
    <meta property="og:url" content="https://example.com/" />
    <meta property="og:type" content="website" />
    <meta property="og:image" content="https://example.com/public/images/icon/ogp_default.jpg" />
    <meta name="twitter:title" content="トップページ" />
    <meta name="twitter:description" content="サイトのトップページです" />
    <meta name="twitter:url" content="https://example.com/" />
    <meta name="description" content="サイトのトップページです" />
    <link rel="canonical" href="https://example.com/" />
    <title>トップページ</title>
    <script type="application/ld+json">
      {
        "@context": "http://schema.org",
        "@type": "BreadcrumbList",
        "itemListElement": [
          {
            "@type": "ListItem",
            "position": 1,
            "item": {
              "@id": "https://example.com/",
              "name": "HOME"
            }
          }
        ]
      }
    </script>
    <script type="module" crossorigin src="./assets/index.min.js"></script>
  </head>
  <body>
    <header>ヘッダー要素</header>
    <main class="page-home">
      <h1>トップページ</h1>
      <p>トップページのコンテンツです</p>
    </main>
    <footer>フッター要素</footer>
  </body>
</html>
  Handlebarsも便利ですが、より複雑な分岐などが必要な場合にはPugの方が使いやすいかもしれませんね。同じ環境で使い分けられるようにしておくと便利ですね。    
Markuplintに対応させる
これまでの内容でPugのコンパイル環境には対応できるようになりましたが、先日の記事(ViteでMarkuplintとPrettierを使える環境を構築する)で紹介したMarkuplintにも対応できるように設定していきます。Pugに対応するためには専用のパーサーが必要になるのでインストールしていきます。
$ npm install --save-dev @markuplint/pug-parser
  Markuplintに必要な設定を追記します。これはPug以外のパーサーを使う場合でも同じですね。 【.markuplintrc.json】※一部抜粋
{
  .....
  "parser": {
    .....
    ".pug$": "@markuplint/pug-parser"
  },
}
  リンター実行のコマンドに、Pugファイルも対象となるように拡張子を追記します。 【package.json】※一部抜粋
{
  "scripts": {
    ....
    "lint:html": "markuplint src/**/*.{html,hbs,vue,pug}",
  },
}
  これでリンター実行時にPugファイルもチェックされるようになります。  
  ページ数やコンポーネントが増えてくるとこのようにテンプレートエンジンを使用することで、より効率よくコーディングすることができます。Pugは記法もシンプルでいろんな処理が用意されていたり、ドキュメントなどの情報も充実している印象ですので、選択肢としてViteの環境でも是非使えるようにしておきたいですね。   (参考にさせていただいたサイト) GitHub SubZtep / vite-plugin-pug
  • はてなブックマーク
  • Pocket
  • Linkedin
  • Feedly

この記事を書いた人

Twitter

sponserd

    keyword search

    recent posts

    • Twitter
    • Github
    contact usscroll to top
      • Facebook
      • Twitter
      • Github
      • Instagram