オススメnode-modules
手指がカサつき過ぎて指紋認証が出来ない小飼です。
フロントエンド開発においてデファクトスタンダードとなった感のあるnpm
は、
Node.js
コミュニティによる開発の活発な無数のライブラリ群があり、Node.js
そのものの魅力に大きく貢献しています。
そこで本稿では私の気に入っているnpm
を、活用範囲をフロントエンドに限らずいくつかご紹介します。
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)); // <script>alert("実行可能")</script>
escape-regexp
正規表現用に文字列をエスケープします。
import escape from 'escape-regexp';
const dangerStr = 'そのままでは/使えない/';
console.log(escape(dangerStr)); // そのままでは/使えない/
uuid
ユニークな文字列を生成します。
import uuid from 'uuid';
const mytoken = uuid.v1();
console.log(mytoken); // 19943a60-7182-11e5-9c4f-3738ae6ba773
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暗号化のライブラリ。
安全性と比例して処理時間は長くなります。
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
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
コマンドのラッパーライブラリ。
タスクランナーに混ぜ込んで静的ファイルの生成
>リモートにコピー
とすると簡易デプロイツールとして使えます。
import scp from 'scp';
scp.send({
file : './.build/*',
host: 'myhost.com',
user: 'myhost',
port: 2222,
path: '/',
});
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シンタックスで定期的に実行したい関数が登録できるライブラリ。
通常の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
keyとvalueが同じプロパティを作ります。
React/Flux
のexampleで使われていますが、
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
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
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
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
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
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にご相談下さいませ!