シアトルコンサルティング サービス開発ブログ

シアトルコンサルティング株式会社プロダクトソリューション事業部の開発ブログです

Gruntでjadeコンパイルするときのあれこれ

こんにちは iijmyaです。

Gruntプラグイン'grunt-contrib-jade'でjadeファイルをコンパイルする際に、
jadeファイルで使いたい値をGruntfileから渡したり、あるディレクトリ以外のjadeファイルをコンパイルしたかったりしたので、自分なりにGruntfile.coffeeに書いてみました。

f:id:seattleservice:20140206161614p:plain


1.jadeファイルで使いたいオブジェクトをGruntfileから渡す

外部から変数を定義するときは dataオプションを使用します。

data: function(dest, src)
	return {
		from: src,
		to: dest
	}

この関数は宛先(dest)と送信元(src)を引数として持ち、データオブジェクトを返します。


例えばjadeファイル内で、ページによって異なるクラス名を付けたいシチュエーションがありました。
変数bodyに、コンパイルするjadeファイルの直近のディレクトリ名を渡したい…

body(class="#{body}")

今回コンパイルするのは以下のファイルで、publicディレクトリの下に配置されます。

  • src/jade/exam/index.jade -> public/exam/index.html

今回の実現したい事に対して、dataオプションは以下のように書いてみました。

data: (filepath)->
	dir = filepath.replace('public/', '').replace(/[^\/]+\.[^\/]+/, "");
	dir = dir.split("/").join("");

	return {body: dir}

宛先のパスを引数として受け取り、余分な文字をreplaceメソッドで削って、最終的にキーがbodyで値がディレクトリ名のオブジェクトデータを返しています。


実際にGruntでwatchをしつつ、src/jade/exam/index.jadeを更新して生成したhtmlを見てみると。。

<body class="exam">

ちゃんと値が入っていました!
dataオプションには、このように関数を定義してデータオブジェクトを渡す他にも、直接データオブジェクトを渡したり、JSONファイルを読み込む事も出来るようなので、詳しくは以下のサイトを見てみてください。
gruntjs/grunt-contrib-jade · GitHub


2.あるディレクトリ以外のjadeファイルをコンパイルする

このディレクトリに入ってるjadeファイル以外をコンパイルしたい…
だからといってコンパイルしたくないファイル以外をいっこずつ指定するのは面倒ですよね。
そんなときはglobパターンを用います。

  * : 0字以上の任意の文字列にマッチする
  ? : 1字の任意の文字列にマッチする
  ** : パスの一部を含む0字以上の任意の文字列にマッチする
  ! : 指定したパターンでない文字列にマッチする
  {,} : カンマ区切りのor条件として、いずれかの文字列を含むかどうかをチェック出来る


例えば以下のようなファイルがあるとします。

  • src/jade/index.jade
  • src/jade/exam/index.jade
  • src/jade/study/index.jade
  • src/jade/parts/layout.jade
  • src/jade/parts/header.jade
  • src/jade/parts/footer.jade

この場合、partsディレクトリ内のjadeファイルを指定するには以下のようになります。

	src: 'src/jade/parts/*.jade'

または

	cwd: 'src/jade/parts/'
	src: '*.jade'


今回実現したかった、「あるディレクトリ以外のファイルをコンパイルしたい」ですが、
partsディレクトリ内のjadeファイルはhtml単体では意味をなさないため、
partsディレクトリ以外のjadeファイルをコンパイル対象に指定します。

src: [
	'src/jade/**/*.jade'
	'src/jade/!parts/*.jade'
]


cwd: 'src/jade/'
src: [
	'**/*.jade'
	'!parts/*.jade'
]

この設定でコンパイルを行ったところ、

$ grunt
Running "watch" task
Waiting...OK
>> File "src/jade/parts/layout.jade" changed.

Running "jade:compile" (jade) task
File "public/exam/index.html" created.
File "public/index.html" created.
File "public/study/index.html" created.

Done, without errors.

partsディレクトリ内のファイルを更新してみても、
ちゃんとpartsディレクトリ以外のファイルがコンパイルされました!


Gruntfileの大まかな書き方さえわかってしまえば、
Gruntはプラグインも豊富なのでいろいろと便利になりそうですね。


今回のjadeタスクの全体像は以下になります。

# Gruntfile.coffee
jade: 
	compile:
		options:
			pretty: true   # インデント有効化
			data: (filepath)->
				dir = filepath.replace('public/', '').replace(/[^\/]+\.[^\/]+/, "");
				dir = dir.split("/").join("");

				return {body: dir}

		files: [
			expand: true
			cwd: 'src/jade/'
			src: [
				'**/*.jade'
				'!parts/*.jade'
			]
			dest: 'public/'
			ext: '.html'
		]