よく使うnode.jsのモジュールを5つ紹介します

ChainZ(クリエイター)
いろいろやってます。

async

async(https://github.com/caolan/async)はもう公式のutilに入れてほしいぐらい使いまくっているモジュールです。node.jsは非同期なので、普段JavaScriptに使うループ式は実用性は低いので、その代わりにasync.each、async.mapなどを使うことが多いです。

async.each

基本形式:

async.each(Array, Callback1(Element, done), Callback2)
async.eachSeries(Array, Callback1(Element, done), Callback2)
// eachSeriesが順番処理です。

Array配列の各要素がElementに渡され、Callback1doneが要素処理のコールバックで、「処理完了」というフラグに使います。doneに第一引数が渡されたら(例えばdone(err))、ループから脱出し、Callback2doneの引数が渡されてコールされます。

var async = require('async');
var fs = require('fs');
var files = [
"./path/to/file1",
"./path/to/file2",
"./path/to/file3"
];
// filesをイテレートする
async.each(files, function(f, done){
fs.exists(f, function(exist){
// ファイルが存在しない場合は、doneをコールし、スキップします
if (! exist) return done();
fs.readFile(f, function(err, data) {
// errの場合はerrをdoneに渡して、脱出します。
if (err) return done(err);
// 無事に処理が終わったら、ファイルの中身をプリントする
console.log("Content of " + f + ":");
console.log(data.toString());
done();
});
});
}, function(err) {
if (err) console.log(err);
console.log('Done');
})

Objectをループしたい場合は、Object.keysを利用して、Objectkeyをイテレートします:

var player = {
name: 'Asuka',
power: 9000,
sex: female,
};
async.eachSeries(Object.keys(player), function(k) {
console.log("Playerの" + k + "の値は: " + player[k]);
}, function() {
console.log("Done");
});

async.waterfall

メソード名waterfallから分かると思うが、滝みたいに順番を処理していくメソードです。

function Initialize(callback){
var app = new App;
if (app.init()) {
console.log("app初期化");
callback(null, app);
} else {
callback(new Error('初期化失敗');
}
}
function Up(app, callback) {
if (! app.up()) return callback(new Error('アプリ起動できませんでした。');
callback(null, app);
}
function initModels(app, callback) {
var models = Models.init();
if (! models) return callback(new Error('モデル初期化エラー'));
app.models = models;
callback(null, app);
}
async.waterfall([
Initialize,
Up,
initModels,
], function(err, app) {
if (err) return console.log(err);
console.log("Done");
});

上記は仮の例ですが、アプリの初期化から、起動、モデルの初期化までの各処理を関数化して、waterfallを使ってステップバイステップで実行されます。もしappに対して新しい処理をやりたければ、新しい関数を作成し、waterfallの順番を見て適切なところに入れれば済むのです。middlewareパターンと似ています。

asyncはプログラミングでよく使うロジックメソードがたくさん入っています。node.jsプロジェクトでは欠かせないモジュールとも言えると思います。

commander

コマンドツールを作る定番のモジュールです。apiが非常に使いやすいです。

#!/usr/bin/env node
var program = require('commander');
program
.version('0.1.0')
.command('hello')
.option('-l, --langauge [value]', 'say hello in specified language', null)
.action(hello)
function hello(options) {
var lang = options.language || 'english';
switch (lang.toLowerCase()) {
case 'english':
console.log('Hello');
break;
case 'japanese':
console.log('こんにちは');
break;
case 'chinese':
console.log('你好');
break;
default:
console.log("Sorry, I don't know the language.");
break;
}
}
program.parse(process.argv);

上記のコードを./sayというファイルとして保存して、コマンドツールで

./say hello

を叩くと:

Hello

が表示されます。-lオプションをつけてみます:

./say hello -l=japanese
こんにちは
./say hello --language=Chinese
你好
./say hello --language=Kansaiben
Sorry, I don't know the language.

commanderはアプリのコンソールツールを作成するに、非常にパワフルで便利なモジュールです。

String.js

String.jsは(http://stringjs.com/)、JavaScriptのStringオブジェクトに不足しているメソードをよくカバーしてくれるモジュールです。

var S = require('string');
// 繰り返す
S("=").repeat(10).s // ==========
// スペースを取り除く
S(" Hello ").trim().s // "Hello"
// スラッグ化
S("A awesome post").slugify().s // a-awesome-post
// 文字列を短縮
S("A very very very long title").truncate(11).s // A very very...
// HTMLをエスケープする
S('<div>Hello</div>').escapeHTML().s; //&lt;div&gt;Hello&lt;/div&gt;
// 文字列が存在するかどうか
S('Hello Asuka!').contains('Asuka') // true
// 頭の文字を大文字にする
S("i am a title").capitalize().s // I'm a title
// HTMLのタグを取り除く
S('<header><h1>タイトルです</h1></header>').stripTags().s // タイトルです
S('<header><h1>タイトルです</h1></header>').stripTags('header').s // <h1>タイトルです</h1>

string.jsを使えば、文字列の処理が相当楽になります。おすすめです。

moment.js

momnet.jsは(http://momentjs.com/) フロントとバックエンド両方使える、時間処理のモジュールです。

// 現在の時間を取得
moment().format('MMMM Do YYYY, h:mm:ss a'); //2015-05-31T19:23:03+09:00
// 相対時間
moment("20150529", "YYYYMMDD").formNow(); //
// カレンダー時間
moment().add(1, 'days').calendar();

公式サイトで詳しい説明が載ってあるので、もっと知りたい方は公式サイトを参考してください。

node-fs-extra

fs-extra(https://github.com/jprichardson/node-fs-extra)名前通り、ネイティヴモジュールfsを拡張したバージョンです。必要とは言えないが、DRYを求める人には便利なツールだと思います。個人でよく使っています。

fs.copy

ファイルを指定した場所に保存する:

var fs = require('fs-extra');
fs.copy("/source/file", "/dest/file", function(err){
if (err) return console.log(err);
console.log("/source/fileを/dest/fileにコピーしました");
});

fs.ensureDir

フォルダを確保する:

fs.ensureDir("/create/me", function(err){
if (err) return console.log(err);
fs.writeFile("/create/me/text.txt", "Hello World", function(err) {
if (err) return console.log(err);
console.log("Done");
});
});

そのほかにも便利なメソードがたくさんあります。公式のドキュメントを参考してください。

まとめ

node.jsには優秀なモジュールがいっぱい揃っています。モジュールをうまく使えば開発が倍速になります。もちろん、使いすぎるとモジュール依存が強くなって、保守には難しくなるリスクもあります。ここで紹介したモジュールはどれも安定しているので、プロダクションに使っても問題ないと思います。