フロントエンド

オススメnode-modules

MMM Corporation
mmmuser

手指がカサつき過ぎて指紋認証が出来ない小飼です。

フロントエンド開発においてデファクトスタンダードとなった感のあるnpmは、
Node.jsコミュニティによる開発の活発な無数のライブラリ群があり、Node.jsそのものの魅力に大きく貢献しています。
そこで本稿では私の気に入っているnpmを、活用範囲をフロントエンドに限らずいくつかご紹介します。

validator

validator

与えられた文字列を検証したり無害化します。

import validator from 'validator';
const inValidMail = 'test@test,com'
const dangerInput = '<script>alert("実行可能")</script>'
console.log(validator.isEmail(inValidMail)); // false
console.log(validator.escape(dangerInput)); // &lt;script&gt;alert(&quot;実行可能&quot;)&lt;&#x2F;script&gt;

escape-regexp

escape-regexp

正規表現用に文字列をエスケープします。

import escape from 'escape-regexp';
const dangerStr = 'そのままでは/使えない/';
console.log(escape(dangerStr)); // そのままでは/使えない/

uuid

uuid

ユニークな文字列を生成します。

import uuid from 'uuid';
const mytoken = uuid.v1();
console.log(mytoken); // 19943a60-7182-11e5-9c4f-3738ae6ba773

autolinker

autolinker

与えた文字列内のURL, メールアドレス, Twitterアカウントを判別してリンク化します。

import Autolinker from 'autolinker';
const linkedText = Autolinker.link('パッケージのURLはhttps://www.npmjs.com/package/autolinkerです');
console.log(linkedText);
// パッケージのURLは<a href="https://www.npmjs.com/package/autolinker" target="_blank">npmjs.com/package/autolinker</a>です

bcrypt

bcrypt

主にパスワードなどの暗号化に用いるbcrypt暗号化のライブラリ。
安全性と比例して処理時間は長くなります。

import bcrypt from 'bcryptjs'
import Promise from 'bluebird'

// 暗号化演算の回数 2の10乗
// この数字に比例して
const SALT_WORK_FACTOR = 10;

// 同期処理用のAPIも用意されているが、
// 暗号化処理の重さを考え非同期処理を採用した
function generateSalt(rawPassword) {
  return new Promise((resolve, reject)=> {
    bcrypt.genSalt(SALT_WORK_FACTOR, (err, salt)=> {
      if (err) {
        return reject(err);
      }
      resolve({ rawPassword, salt });
    });
  });
}

function hashPassword({ rawPassword, salt }) {
  return new Promise((resolve, reject)=> {
    bcrypt.hash(rawPassword, salt, (err, hash)=> {
      if (err) {
        return reject(err);
      }
      resolve(hash);
    });
  });
}

function saveDB(hashedPassword) {
  return new Promise((resolve, reject)=> {
    // DB保存の処理
  });
}

generateSalt()
.then(hashPassword)
.then(saveDB)
.finally(next);

// 復元して検証
function inspectionPassword(candidatePassword, hashedPassword) {
  return new Promise((resolve, reject)=> {
    bcrypt.compare(candidatePassword, hashedPassword, (err, isMatch)=> {
      if (err) {
        return reject(err);
      }
      resolve(isMatch);
    });
  });
}

参考: 筆者の開発環境で暗号化部分のテストコードをSALT_WORK_FACTOR定数の値を変えて走らせてみた結果

SALT_WORK_FACTOR テスト完了までの時間
10 273ms
11 491ms
12 992ms
13 1876ms
14 3742ms
15 7613ms
20 250873ms

levenshtein

levenshtein

2つの文字列間の距離(差異)を算出するレーベンシュタイン距離アルゴリズムのライブラリです。

import Levenshtein from 'levenshtein';

const baseString = 'Hello, world';
const diffString = 'Hey, world';
const l = new Levenshtein(baseString, diffString);

console.log(l.distance); // 3
console.log(l);
/*
 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10 |11 |12
---+---+---+---+---+---+---+---+---+---+---+---+---
 1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10 |11
---+---+---+---+---+---+---+---+---+---+---+---+---
 2 | 1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10
---+---+---+---+---+---+---+---+---+---+---+---+---
 3 | 2 | 1 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10
---+---+---+---+---+---+---+---+---+---+---+---+---
 4 | 3 | 2 | 2 | 2 | 3 | 3 | 4 | 5 | 6 | 7 | 8 | 9
---+---+---+---+---+---+---+---+---+---+---+---+---
 5 | 4 | 3 | 3 | 3 | 3 | 4 | 3 | 4 | 5 | 6 | 7 | 8
---+---+---+---+---+---+---+---+---+---+---+---+---
 6 | 5 | 4 | 4 | 4 | 4 | 4 | 4 | 3 | 4 | 5 | 6 | 7
---+---+---+---+---+---+---+---+---+---+---+---+---
 7 | 6 | 5 | 5 | 5 | 4 | 5 | 5 | 4 | 3 | 4 | 5 | 6
---+---+---+---+---+---+---+---+---+---+---+---+---
 8 | 7 | 6 | 6 | 6 | 5 | 5 | 6 | 5 | 4 | 3 | 4 | 5
---+---+---+---+---+---+---+---+---+---+---+---+---
 9 | 8 | 7 | 6 | 6 | 6 | 6 | 6 | 6 | 5 | 4 | 3 | 4
---+---+---+---+---+---+---+---+---+---+---+---+---
10 | 9 | 8 | 7 | 7 | 7 | 7 | 7 | 7 | 6 | 5 | 4 | 3
*/

scp

scp

scpコマンドのラッパーライブラリ。
タスクランナーに混ぜ込んで静的ファイルの生成>リモートにコピーとすると簡易デプロイツールとして使えます。

import scp from 'scp';
scp.send({
    file : './.build/*',
  host: 'myhost.com',
  user: 'myhost',
  port: 2222,
  path: '/',
});

log4js

log4js

ログ出力ライブラリ。
出力のタイプをコンソールやファイルなどから選択したり、出力先を設定したりできます。

import log4js from 'log4js';

const configure = {
  debug: {
    type: 'console',
    category: 'console',
  },
  warn: {
    type: 'file',
    category: 'file',
    filename: ./file.log,
  },
};

log4js.configure({
  appenders: [
    configure.debug,
    configure.warn,
  ],
});

const consoleLogger = log4js.getLogger('console');
const fileLogger = log4js.getLogger('file');

consoleLogger.info('Hello, console log.'); // [2015-10-20 09:24:22.551] [INFO] console - Hello, console log.
fileLogger.info('Hello, file log.'); // [2015-10-20 09:24:22.555] [INFO] file - Hello, file log.

cron

cron

cronシンタックスで定期的に実行したい関数が登録できるライブラリ。
通常のNode.jsプロセスなので、バックグラウンドで実行するには別のライブラリとの併用が必要になります。

import { CronJob } from 'cron';
const everyMorning = '0 0 8 * * *';

const job = new Cronjob({
  cronTime: everyMorning,
  onTick() {
    console.log('Good morning.');
  },
  start: false,
});

job.start();

keymirror

keymirror

keyとvalueが同じプロパティを作ります。
React/Fluxexampleで使われていますが、
babelでコードを書くことが増えた最近では使う機会は少なくなってきています。

import keymirror from 'keymirror';
const myObj = keymirror({
  foo: null,
  bar: null,
});
console.log(myObj); // { foo: 'foo', bar: 'bar' }

// bable経由ではこう書ける
const foo = 'foo';
const bar = 'bar';
const es2015Obj = {
  foo,
  bar,
};
console.log(es2015Obj); // { foo: 'foo', bar: 'bar' }

object-assign

object-assign

ES2015のObject.assignメソッドの先取り実装。
これもkeymirrorと同様の理由で、最近は使う機会がありません。

import objectAssign from 'object-assign';
const objA = {
  foo: 'foo',
};
const objB = {
  bar: 'bar',
};
console.log(objectAssign(objA, objB)); // { foo: 'foo', bar: 'bar' }
console.log(Object.assign(objA, objB)); // { foo: 'foo', bar: 'bar' }

q

q

callback地獄に陥らないためのPromiseライブラリの一つ。
後述のbluebirdと並んで2大人気Promiseライブラリという印象があります。

import fs from 'fs';
import Q from 'q';

function readAsync(pathtofile) {
  const deffered = Q.defer();
  fs.readFile(pathtofile, (err, data)=> {
    if (err) {
      return deffered.reject(err);
    }
    deffered.resolve(data);
  });
  return deffered.promise;
}

readAsync('README.md').then((data)=> {
  console.log(data: ${data});
});

bluebird

bluebird

Qと並んで人気のPromiseライブラリ。
個人的な印象としてはこちらのインターフェースの方が直感的に使いやすいと思っています。
また、Node.jsスタイルの関数をPromise化してくれるPromise.promisifyメソッドが非常に有用で、筆者は主にこちらを使っています。

import fs from 'fs';
import Promise from 'bluebird';

function readAsync(pathtofile) {
  return new Promise((resolve, reject)=> {
    fs.readFile(pathtofile, (err, data)=> {
      if (err) {
        return reject(err);
      }
      resolve(data);
    });
  });
}

readAsync('README.md').then((data)=> {
  console.log(data: ${data});
});

// Promise配列を同時に処理したり

Promise.all([readAsync('README-1.md'), readAsync('README-2.md'), readAsync('README-3.md')])
.then((datas)=> {
  console.log(datas: ${datas});
});

// 順番に非同期処理を実行したりできる
function readAsyncReduce(_, pathtofile) {
  return new Promise((resolve, reject)=> {
    fs.readFile(pathtofile, (err, data)=> {
      if (err) {
        return reject(err);
      }
      console.log(${pathtofile}: data);
      resolve();
    });
  });
}

Promise.reduce(['README-1.md', 'README-2.md', 'README-3.md'], readAsyncReduce, null)
.then(()=> {
  console.log('all done.');
});

// コールバック関数の第一引数にエラー、第二引数に処理結果を渡す関数をPromise化してくれる
const readPromisify = Promise.promisify(fs.readFile);

readPromisify('README.md', 'utf-8')
.then((data)=> {
  console.log(data);
});

sequelize

sequelize

SQL系データベースのORMライブラリ。
筆者はMySQL, PostgreSQLでしか活用したことがありませんが、

Sequelize is a promise-based Node.js/io.js ORM for Postgres, MySQL, MariaDB, SQLite and Microsoft SQL Server.

とのことです。

// MySQLでの例
import Sequelize from 'sequelize';

const db = 'mysql://username:password@127.0.0.1:3306/databasename';
const connection = new Sequelize(db);

const UserModel = connection.define('user', {
    mail: {
      type: Sequelize.STRING,
      field: 'mail',
      unique: true,
      validate: {
        isEmail: true
      },
    },
    password: {
      type: Sequelize.STRING,
      field: 'password',
    },
  },
);

UserModel.create({
  mail: 'my-mail@test.com',
  password: 'mypassword',
})
.then((newUser)=> {
  console.log('user saved.');
});

mongoose

mongoose

MongoDBのORMライブラリ。

import mongoose from 'mongoose';

const db = 'mongodb://username:password@127.0.0.1:27017/databasename';
const connection = mongoose.createConnection(db);
const UserSchema = new mongoose.Schema({
  mail: {
    type: String,
    index: {
      unique: true,
    },
  },
  password: String,
});
const UserModel = db.model('user', UserSchema);

const newUser = new User({
  mail: 'my-mail@test.com',
  password: 'mypassword',
});

newUser.save((err)=> {
  console.log('user saved.');
});

まとめ

いくつか駆け足で紹介してみましたがいかがだったでしょうか。
参考になればうれしいです。

Nodeモジュールを活用したフロントエンドアプリケーション開発をご検討の企業様は、是非MMMにご相談下さいませ!

AUTHOR
デロイト トーマツ ウェブサービス株式会社(DWS)
デロイト トーマツ ウェブサービス株式会社(DWS)
デロイト トーマツ ウェブサービス株式会社はアマゾン ウェブ サービス(AWS)に 専門性や実績を認定された公式パートナーです。
記事URLをコピーしました