node.jsでヒアドキュメントとかデータセクション(?)とか

JavaScriptを書いているとたまにヒアドキュメントで文字列を書きたくなったり、Rubyのように__END__以下に書きたくなったりしますが、JavaScriptではできないので、ぐぬぬ、という顔をしてしかたなく文字列を行ごとにArrayに入れ、それをjoin('\n')するか、もしくは+演算子でつなぐ、ということをするかと思います。


で、今日たまたまタイムラインを見ているとこんなツイートが。

node-data-section? node-here? なんだろこれ?とよく知らないモジュールだったので使ってみたのでした。

node-here

名前の通りヒアドキュメントをnode.jsで書けるようにするモジュールです。
npmからのインストールはhereで。

$ npm install here


使い方としては以下のような感じ。

#!/usr/bin/env node

// test-here.js

var here = require('here').here;

console.log(here(/*
  <!DOCTYPE html>
  <meta charset="utf-8">
  <title></title>
  <p>インターネット</p>
*/).unindent());

console.log('');

console.log(here(/*
  <!DOCTYPE html>
  <meta charset="utf-8">
  <title></title>
  <p>インターネット</p>
*/).valueOf());

実行すると以下のような感じに。

$ node test-here.js
<!DOCTYPE html>
<meta charset="utf-8">
<title></title>
<p>インターネット</p>

  <!DOCTYPE html>
  <meta charset="utf-8">
  <title></title>
  <p>インターネット</p>


メソッドが2種類あるみたいで、

unindent 行頭のインデントを無視する
valueOf 値そのまま

を選べるみたい。特に前者のやつはブロックが深いときとかに有用かも。

node-data-section

コメントにデータセクションを書いて使えるようにするモジュールです。
npmからのインストールはdata-sectionで。

$ npm install data-section


使い方以下のような感じ。

#!/usr/bin/env node

// test-data.js

var dataSection = require('data-section');

dataSection.get('data1', function (err, data) {
  if (err) throw err;
  console.log(data);
});

console.log(dataSection.getSync('data2'));

/*__DATA__
@@ data1
data1 text
data1 text
data1 text
@@ data2
data2 text
data2 text
data2 text
__DATA__*/

これを実行してみると

$ node test-data.js
data2 text
data2 text
data2 text
data1 text
data1 text
data1 text

という感じ。


データセクションは

/* __DATA__

が始まりで

 __DATA__ */

で終わるところ。コードを見た感じだとアスタリスクのあとに空白が入っても入らなくても良いみたい。


データセクション内のデータの区切り(?)は

@@ data

で表すのです。ここもアットマークの後の空白は入っても入らなくても良いみたい。


メソッドはいくつかあって、非同期でデータ区切り(?)を指定して取得するgetが以下のとおり。

dataSection.get('aaa', function (err, data) {
  console.log(data.aaa); 
});
/*__DATA__
@@ aaa
aaa
__DATA__*/

非同期で、データを全部取得するgetが以下のとおり。

dataSection.get(function (err, data) {
  console.log(data.aaa); 
  console.log(data.bbb); 
});
/*__DATA__
@@ aaa
aaa
@@ bbb
bbb
__DATA__*/

あと、同期版のgetがそれぞれ以下のとおり。

console.log(dataSection.getSync('aaa'));

var dataAll = dataSection.getSync();
console.log(data.aaa); 
console.log(data.bbb); 
/*__DATA__
@@ aaa
aaa
@@ bbb
bbb
__DATA__*/


他に、ファイル名を指定してそのファイルのデータを取得、なんてこともできるみたい。

// aaa.js
/*__DATA__
@@ aaa
aaa
@@ bbb
bbb
__DATA__*/
var dataSection = require('data-section'),
    FILENAME = require('path').join(__dirname, 'aaa.js');

dataSection.get({filename: FILENAME            }, function (err, data) { console.log(data.aaa); });
dataSection.get({filename: FILENAME, key: 'aaa'}, function (err, data) { console.log(data);     });

var dataAll = dataSection.getSync({filename: FILENAME});
console.log(dataAll.aaa);

var data = dataSection.getSync({filename: FILENAME, key: 'aaa'});
console.log(data);

とかとか。微妙に使いそうかも。


というわけで、ヒアドキュメントとかを使いたい場合などにこの二つのモジュールを検討してみると良いかも!