Category
ウェブ制作

カルアカブログ

これからのコーディングは再利用と効率化だ!Pugをgulpでコンパイル

こんにちは、フロントエンドエンジニアのかみーゆです。

HTMLってネスト(入れ子構造)すればするほど、閉じタグを見失いますよね?
本来であれば深いネストそのものをやめるべきなんですが、デザインを忠実に再現するためにはそうもいかない時があります。ページのコンテンツが増えれば、コメントをしっかり残しておかなければどこをどうコーディングしたか迷子になります。

後から直すたびに残したコメントを検索して探すなど日常茶飯事かと思います^ ^;
Pugは平たく言えばそんな面倒なHTMLをパーツ化して効率よくコーディングできるメタ言語です。メタ言語なので、何かを介してHTMLにコンパイルする必要があります。
今回はPug(旧:Jade)のコンパイルをgulpで自動化する方法をご紹介します。
Pugの詳しい記述方法に関しては、「これからのコーディングは再利用と効率化だ!話題のPugを使ってみた」をまずはお読みください。

この記事は基本ノンプログラマでもコピペしながら通して一つずつやってみることで、理解が深まるように書いているつもりです。より理解したい方は最初から最後までお付き合いください。
すでにわかってる方は、みたいところ以外はすっ飛ばして読んでください。
Macでの作業を想定してます。ご了承ください。

目次
  1. 開発環境の準備
    1. Pugをインストールする
  2. Pugをコンパイルするためのタスクを書く
    1. まずはシンプルにコンパイル
    2. エラーがあってもBrowserSyncの処理をする
    3. コンパイルする・しないファイルをより分ける
  3. サイトの基本情報を設定する
  4. まとめ

開発環境の準備

Pugのコンパイルするために必要なインストールします。

最低条件はnode.jsとnpmをインストールしていることです。もししていないのであればコピペで始めるgulp入門(1):ライブリロード編をご確認いただきインストールしておきましょう。

!コマンド入力するときのお願い!
コードの前に$マーク+スペースがありますが$マーク+スペースは省いてコピペしてください。

前回の「これからのコーディングは再利用と効率化だ!話題のPugを使ってみた」の続きということでPugを扱うディレクトリはpug-testにしてます。前回から続けて作業している方はそのまま作業してください。
cdコマンドで移動します。移動のパスの指定方法が分からない方はcd+スペースの後に、ターミナルにフォルダアイコンをドラッグ&ドロップしてみてください。

コマンド
$ cd pug-testのパス

まずはpackage.jsonを作成します。
以下をコピーしてpackage.jsonファイルを作成して、pug-test直下に配置します。
npm initというコマンドで対話形式でも生成できます。対話形式で作りたい方は、コピペで始めるgulp入門(1):ライブリロード編を参考に作成してみてください。

JSON
{
   "name": "pug-lesson",
   "private": true,
   "version": "1.0.0",
   "description": "practice for pug",
   "main": "index.js",
   "scripts": {
     "start": "gulp"
   }
 }

コードを叩いてモジュールgulp、gulp-pug、browser-syncをローカルにまとめてインストールします。
browser-syncはファイルを更新するたびにブラウザをライブリロードできるモジュールです。

コマンド
$ npm install gulp gulp-pug browser-sync --save-dev

開発用のモジュールなので--save-dev(開発用のモジュール)というオプションをつけておきます。

Pugをコンパイルするためのタスクを追加

まずはシンプルにコンパイル

まずはPugファイルをシンプルにコンパイルするタスクを書いてみましょう。まだ、エラー回避処理がされていないのでエラーがあるとコケます。

pug-test/
├ dev/
│  index.pug
└ dest /

index.pugには以下のコードを書きます。

bodyタグのないhtmlはBrowserSyncしないのでご注意を!
Pug
 doctype html
   html(lang="ja") 
     head
      meta(charset="utf-8")
      title Pugレッスン
     body
       h1 Pug始めました
       main.main
         p Pugでhtml作ったよ
JS
{//モジュール
 const gulp = require('gulp')
 const browserSync = require('browser-sync')
 const pug = require('gulp-pug')

//開発ディレクトリ const devDir = 'dev/' const dev = {   'pug': devDir + '*.pug' }

//Pugをコンパイルするタスク gulp.task('pug', () => {   gulp.src( dev.pug )   .pipe(pug({    basedir: devDir,     pretty: true   }))   .pipe(gulp.dest(destDir)) })

//ブラウザシンク gulp.task('browser-sync', () => {   browserSync({   server: {     baseDir: destDir,     index : 'index.html'   }, }) })

//デフォルト gulp.task('default', ['pug','browser-sync'], () => {   gulp.watch(dev.pug, ['pug'])   gulp.watch([devDir + '**/*.pug').on('change', browserSync.reload) })

Pugのコンパイルオプションのprettyをtrueに設定することでキレイに改行された、HTMLコードが生成されます。

以下コマンドを叩いてみましょう。

コマンド
$ gulp
HTML
<!DOCTYPE html>
 <html lang="ja">
 <head>
   <meta charset="UTF-8">
   <title>Pugレッスン</title>
 </head>
 <body>
   <h1>Pug始めました</h1>
   <main class="main">
     <p>Pugでhtml作ったよ</p>
   </main>
 </body>
 </html>

エラーがあってもBrowserSyncの処理をする

エラーがあってもgulpを止めないgulp-plumber、エラーを通知してくれるgulp-notifiyをインストールします。

コマンド
npm instakk gulp-notify gulp-plumber --save-dev
JS
//モジュール
 const plumber = require('gulp-plumber')
 const notify = require("gulp-notify")
 //Pugコンパイルするタスク
 gulp.task('pug', () => {
 gulp.src( dev.pug )
 .pipe(plumber({errorHandler: notify.onError('Error: <%= error.message %>')}))
 .pipe(pug({
    basedir: devDir,
     pretty: true
   }))
   .pipe(gulp.dest(destDir))
 })

コンパイルする・しないファイルをより分ける

_(アンダースコア)が頭に付与されたファイル名は読込専用のファイルと認識し、コンパイルしないようにします。Sass(SCSS)では_(アンダースコア)が付与されたらインクルード(読取り)用ファイルと自動で認識してくれるのですがPugは手動での設定が必要です。変数dev.pugに対象のパスを指定してますが、続けて'!' + することで特定のファイルがコンパイルの対象から外すことができます。
こうすることでheaderやfooterなどをパーツ化して読込む(include)ことができます。

pug-test/
├ dev/
│ └ inc/
│     _meta.pug
│     _header.pug
│     _footer.pug
│     _layout.pug
│  index.pug
└ dest /

dev.pugを以下に書き換える。

JS
const dev = {
 'pug': [devDir + '**/*.pug', '!' + devDir + '**/_*.pug']
 }

テンプレート化します。詳しくは「これからのコーディングは再利用と効率化だ!話題のPugを使ってみた」のテンプレート化してみるを参考にしてください。

Pug/index.pug
 extend /_inc/_layout
 block content
   section
     p test
Pug/_layout.pug
doctype html
 html(lang="ja")
   head
     include /_inc/_meta
   body
     include /_inc/_header
     block content
     include /_inc/_footer
Pug/_meta.pug
 meta(charset="UTF-8")
 meta(name="viewport" content="width=device-width, initial-scale=1.0")
 meta(http-equiv="X-UA-Compatible" content="ie=edge")
Pug/_header.pug
 .l-header
   .l-lheader_logo サイトロゴ
Pug/_footer.pug
.l-footer
   .l-lheader_copy
     small (c) コピーライト

ではコンパイルしてみましょう。

コマンド
$ gulp

以下のようなHTMLが生成されます。

HTML
<!DOCTYPE html>
 <html lang="ja">
   <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <meta http-equiv="X-UA-Compatible" content="ie=edge">
   </head>
   <body>
     <div class="l-header">
       <div class="l-lheader_logo">サイトロゴ</div>
     </div>
     <section>
        <p>test</p>
     </section>
     <div class="l-footer">
       <div class="l-lheader_copy"><small>(c) コピーライト</small></div>
   </div>
 </body>
 </html>

サイトの基本情報を設定する

Pugを使えば、CMS的にページを量産できます。Pugでコンパイルしたまんまファイルをリリースしたい場合は、基本のメタtitleやメタdescriptionなど設定しておきたいですよね?そういった場合は、基本情報をJSONデータを設定しておけば楽チンです。
まずは、JSONデータを読み込めるために必要なモジュールをインストールします。

コマンド
npm install gulp-path gulp-data rs --save-dev

サイトの基本情報も格納するJSONファイルを作ります。

JSON
{
   "name": "サイトの名前",
   "description": "サイトの説明",
   "ogp":{
     "image": "/assets/images/logo.png"
   }
 }

最近は構造化データもSEOで重要なのでそういった情報も入れておくと良いですね。

gulpfile.jsに以下のようにタスクを追記します。
localsの値にJSONデータを渡します。

JS
//モジュール
 const fs = require('fs')
 const data = require('gulp-data')
 const path = require('gulp-path')
 //pug
 gulp.task('pug', () => {
 const siteinfo = {
   'site': JSON.parse(fs.readFileSync(dev.data))
 }
 gulp.src( dev.pug )
   .pipe(plumber({errorHandler: notify.onError('Error: <%= error.message %>')}))
   .pipe(pug({
     locals: siteinfo,
     basedir: devDir,
     pretty: true
   }))
   .pipe(gulp.dest(destDir))
 })

メタ要素を管理する_meta.pugに以下のコードを付与します。

Pug:_inc/_meta.pug
block variables
 doctype html
 html(lang="ja")
   head
     meta(charset="UTF-8")
     meta(name="viewport" content="width=device-width, initial-scale=1.0")
     meta(http-equiv="X-UA-Compatible" content="ie=edge")
     title #{pageTitle} | #{site.name}
     // ogp
     meta(property="og:type" content="Website")
     meta(property="og:image" content=site.ogp.image)
     meta(property="og:title" content=site.name)
     meta(property="og:url" content=site.url)
     meta(property="og:description" content=site.description)

ページごとにタイトルも設定しておきます。

meta(property="og:description" content=site.description)

Pug:index.pug
append variables
 - var pageTitle = 'トップページ';

コマンドを叩いてコンパイルします。

コマンド
$ gulp

以下のようにしっかりJSONデータも反映しています。

HTML
<!DOCTYPE html>
   <html lang="ja">
     <head>
       <meta charset="UTF-8">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <meta http-equiv="X-UA-Compatible" content="ie=edge">
       <title>トップページ | サイトの名前</title>
      <!-- ogp-->
     <meta property="og:type" content="Website">
     <meta property="og:image" content="/assets/images/ogp.png">
     <meta property="og:title" content="サイトの名前">
     <meta property="og:url" content="http://URL">
     <meta property="og:description" content="サイトの説明">
   </head>
   <body>
     <div class="l-header">
       <div class="l-lheader_logo">ロゴ</div>
     </div>
     <section>
       <p>test</p>
     </section>
     <div class="l-footer">
       <div class="l-lheader_copy"><small>(c) LEAD Space</small></div>
     </div>
   </body>
 </html>

まとめ

Pugは静的ページの量産や長いコンテンツをコーディングするときに重宝します。

ぜひ試してみてください。

Tags
gulp
node.js
Pug

関連記事

関連サービス