Help us understand the problem. What is going on with this article?

gulp-jade で JSON ファイルを変数に読み込む方法(gulp-pug v2 対応追記)

More than 3 years have passed since last update.

jade でサイトを作成していると、共通情報は外部ファイルにまとめて記述したくなります。やはり jade なので、外部ファイルは JSON 形式にまとめておきたいところですね。

先に結論

gulp-data を使いましょう。
gulp-jade に使い方も紹介されてます。

gulp-data を使わない方法

公式の方法に辿り着く前に、ろくすっぽ調べずに自己流で JSON データをパースしてました…。
果たしてこの方法に需要があるのかどうか分かりませんが、試行錯誤の時間を無為にするのも悔しいので、まあ、こんな方法もあるよーということで、晒しておきます。

site.json
{
  "name": "サイトタイトル",
  "root": "/"
}
demo.jade
//- パースしたJSONデータを格納するグローバル変数
- var data = {}

//- JSON 構文をパースしてグローバル変数の data にデータを格納する mixin
mixin json(name)
  - var oldbuf = buf
  - buf = []
  block
  - data[name] = JSON.parse(buf.join(''))
  - buf = oldbuf

//- 外部 JSON 情報の読み込み
+json('site')
  include site.json

//- 呼び出し
h1: a(href=data.site.root) #{data.site.name}

解説

jade 標準出力を横取りして JSON をパースしてます。
最後に読み込んだ JSON が標準出力されないよう、バックアップしていた buf を書き戻してます。 buf は jade の mixins で使われている内部変数ですので、あまり行儀の良いやり方ではありませんが…

強いてこの方法の利点を挙げれば

  • gulpfile.js に 設定ファイルの記述なしに jade の構成ファイルの記述内で完結できる
  • gulp-data が何らかの理由により使えない環境の代替となる

と言ったところでしょうか。

gulp-pug v2 対策(2016年6月23追記)

jade は商標の問題から、pug に名前が変わりました。また、2016年6月23時点で v2.0 がベータ版リリースされていますが、v1.11から いろいろと内部構成が変わっていて、前述の mixin で横取りする方法が使えなくなりました。

素直に gulp-data を使った方が良さそうですが、ページ毎に適用する JSON ファイルを変更するような運用にしたいので、JSON ファイルの指定は gulpfile.js ではなく、pug ファイル側で指定したいところです。
pug 自体に外部 JSON ファイルをパースする機能があれば良いのですが、残念ながら現時点では自前で用意するしかなさそうです。

タスク側から pug に記述した JSON ファイルを取得する

pug 本体に手を加えるのは時間がかかりそうなので、手っ取り早く gulpfile.js のタスク処理側でカバーします。
ページ側に特定書式コメントの JSON ファイルのパスを指定しておき、タスクの gulp-data 経由で JSON ファイルを読み込むようにします。

pug コメントの後に続けて data path/to/filename.json と記述するルールとします。

demo.pug
//-data site.json

//- 呼び出し
h1: a(href=data.site.root) #{data.site.name}

pug コンパイルのタスクで、前述の JSON パスコメントを検知して、オブジェクトとして取り込むように、以下のように記述します。

gulpfile.js
'use strict';

var gulp = require('gulp');
var pug  = require('gulp-pug');
var data = require('gulp-data');

gulp.task("pug", function(){
  return gulp.src("./*.pug")
    .pipe(data(function(file) {
      var json = {};
      String(file.contents).split("\n").forEach(function(line) {
        if(line.match(/^\/\/\-\s*?data\s+?((\w+)\.json)$/)) {
          json[RegExp.$2] = require("./" + RegExp.$1);
        }
      });
      return { data: json };
    }))
    .pipe(pug({
      pretty: true
    }))
    .pipe(gulp.dest("./"))
   ;
});

これで 指定した JSON ファイルの内容を data.[ファイル名] のデータとして pug から参照できるようになりました。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした