Node.js を選ぶとき
選ばないとき

東京Node学園祭 2013
2013.10.26

Sapporo.js
佐藤 竜之介(Ryunosuke SATO)
提供
Community for people who like JavaScript.

Sapporo.js
自己紹介
@tricknotes
I am a software developer who
love JavaScript and Ruby.

http://tricknotes.hateblo.jp/
I love OSS
I am a contributer

of Ember.js
Sapporo.js
http://sapporojs.org/
/*
* advertising
*
* !!Important!!
*
2013.11.30

JavaScript 道場
http://connpass.com/event/3674/
n
i

幌
札

2013.11.30

JavaScript 道場
http://connpass.com/event/3674/
Idobata
https://idobata.io
*/
よろしく
お願いします
Node.js を選ぶとき
選ばないとき

東京Node学園祭 2013
2013.10.26

Sapporo.js
佐藤 竜之介(Ryunosuke SATO)
今日の話

私が web アプリケーション を作るときに、
Node.js を選んだ場面、選ばなかった場面があります

そのときの背景を交えつつ、 Node.js と Rails
を比較し Node.js の適切な使い所について考察
します
Why Rails?
Node.js ライブラリには Ruby / Rails の影響を
受けているものが多い
*
*
*
*

Rails(generator)<->
Sinatra
<->
Sprockets <->
Rails
<->

yeoman
Express
Mincer
Sails

なので、有意義な比較ができそう
対象者

* Node.js 以外の選択肢を知らない方
* Node.js をあまり使ったことがない方
注意
早く快適にアプリケーションを開発する、
ということに主眼を置いて考察していきます
パフォーマンスやサーバリソースなどの
優先順位は低めです
さて、みなさんが web ア
プリケーション を作りはじ
めるとき、どういう基準でそ
の手段を選ぶでしょうか?
Node.js の場合
Node.js での web アプリ
ケーション開発について
確認してみましょう
http://nodejs.org/
まずは素の状態で始めてみる
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello Worldn');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');

$ curl http://localhost:1337
Hello World
Node.js の基本的な仕組みを理解する
には大事な一歩

でも、これだけだとまだまだ簡単には作れそうにない
実際にはもっと複雑なアプリケーション
を作ることになるでしょう

複雑さに立向うために
ライブラリを使う
http://expressjs.com/
例えば、 express を使ってみる
var express = require('express');
var app = express();
app.get('/', function(req, res){
res.send('Hello World');
});
app.listen(3000);
express はとてもシンプル
コアが大きくないし、拡張も簡単
ただ、自由度が高いために整理するのに工夫が必要
確かに、express だと、
学習コストは低いかもしれない

学習コスト?
開発速度を維持するコスト?
どっちが大事?
もうすこし大きなフレームワークを好むひともいるか
もしれない
http://sailsjs.org/
model 周りが貧弱
* 関連を扱えない
* マイグレーションがない

データベースとつなげればいいんじゃなくて、
ドメインロジックの管理も適切に行いたい...!!

そこまで大きな手助けしてくれるフレームワークでは
ないのでは...?
最初に大長編 Gruntfile.js を生成する

生成されたコードはバージョンアップに
追従するのが面倒
デフォルトで上手いことやってほしい
http://gruntjs.com/
contlib で様々なタスクが配布され
ているのはありがたい

but...
設定を毎回書くのは手間
grunt.loadNpmTasks('grunt-contrib-coffee');

grunt.initConfig({
coffee: {
compile: {
files: {
'result.js': 'source.coffee'
}
}
}
});
もっと、スムーズに開発を進めたい...!!
Rails の場合
Asset pipeline
* CoffeeScript や Sass のコンパイル
* asset ファイルの minify, concat
* digest hash の付与
Grunt 使ってやりたくなるようなことは、
デフォルトでやってくれる
Asset pipeline
* application.js
//= require jquery
//= require underscore
//
//= require app
application.js にリクエストを投げると、
すべて連結して取得できる
ビルド時には minify + digest が付与される
ビルドタスク
$ rake asset:precompile

そもそもデフォルトで入っている
js のライブラリの管理
* jquery-rails
* underscore-rails
* moment-rails
...

assets のパスが追加される、だけ
静的なファイルをリポジトリに含めなくてOK
ActiveRecord
*
*
*
*

validation
relation
migration
ドメインロジックの管理
一本の道があるということ
の良い所
その道に沿うように他のライブラリが成長していく

Rails に乗る形で、まとまった単位の機能を提
供するライブラリが多い
* 画像アップロード -> carrierwave
* 認証管理 -> devise
* OAuth provider -> doorkeeper

やりたいことを実現するまでの手数が少ない
ちょっと基本に立ち返る
そもそも、Node.js と
Rails ではスタートが違う
“Evented I/O for V8 javascript.”
あくまで、非同期 IO の環境
web 開発以外でも活躍している
http://nodeos.github.io/
https://github.com/rogerwang/node-webkit
“Web development that does’t hurt”
web 開発のためのフレームワーク
7 年かけて環境が整備されてきている
フレームワーク
ライブラリ
言語(実装)
言語(仕様)
Rails が開発効率に重点を置いているので、
使いやすいのは納得できる
Node.js では、まだその大きさのフレーム
ワークは出てきてなくて、 小回りが効くライ
ブラリが多い
Node.js にも、 道を敷いてくれるような
フレームワークがあるとよいの...?

そうでもない、ような...
私の例
自分の例①

->
NotHub
http://nothub.org/
NotHub
* GitHub のイベントをリアルタイムに通知する
Chrome Extension
* 受け取るイベントを設定可能
* public なリポジトリ限定
よくある使い方

* ライブラリのバージョンアップを早く知りたい
* 自分のリポジトリが star されたのを知りたい
* 興味があるハッカーの活動を知りたい
GitHub API

Pub

Crawler

Redis

Sub

Publisher

Chrome Extension

crawl
最初は Ruby で書き始めたが、
パフォーマンスでなくて Node.js で書き直した
* GitHub の API をとにかく叩く必要があった
* Ruby でマルチスレッド処理するのは意外と面倒
* Ruby で非同期書くのも手間
そもそも、Rails が得意な
分野ではない
通知の部分は単純な push 通知なので、
Socket.IO がフィットした
ビルドタスクは Rake
当時は Grunt の開発が始まったばかり
Chrome Extension をパッケージしたい
今だと Grunt を使うかも
自分の例②

->
starseeker
http://starseeker.so/
starseeker
* GitHub の followings の star を
daily メールでお知らせする web アプリ
* リアルタイムじゃなくてアーカイブ
よくある使い方

* 良さそうなライブラリを知る手がかりに!!
* 朝、仕事を始める前に hot なリポジトリをチェック
GitHub API

save

Crawler

MongoDB

read
Web Application

PostgreSQL

crawl
*
*
*
*

Crawl したデータを MongoDB へ
MongoDB なら Node.js と思って書き始めたが...
ユーザ管理とか OAuth 周りが意外と面倒
Rails でやることに
Crawl する部分は Node.js
メール配信も、Rails がいい感じにフィットした
* html/text の multipart メール
* html とのコード共有
<->
両方ともそれぞれに良さがあるので、
それぞれに適切な場面がある!!
よくある誤解集
これだけで選択するのは
まだ早い
‘

クライアントとサーバの
言語統一できて開発がはかどる
* DOM を扱う JavaScript と、ネットワーク、
ドメインロジックを扱う JavaScript は違う
* 確かに言語は統一できるけど、思考の
スイッチングコストは発生する
イベント発火だけでも結構違う
// DOM

jQuery('form').trigger(‘form’);
// Node.js

stream.emit('fetch’, data);
‘

クライアントとサーバで

ロジックの共有がスムーズにできる
* サーバ側でもクライアント側でも使いたい
ロジックはそこまでないのでは...?
* utility 的な関数群だと、ありえるかも
* underscore.js など既存のライブラリ
を使いましょう
互換性のあるコードを維持するのは結構手間

関数定義の工夫
var exports = typeof(module) === 'undefined' ?
this :
module.exports;
exports.method = function() {
// ...
};
互換性のあるコードを維持するのは結構手間

対象ブラウザで使えないメソッドのチェック

array.every(function() {
// ...
});
fn.bind(this);
‘

簡単にスケールできる
* 採用するアーキテクチャに依存する
* Node.js を使っていてもある程度想定して
おかないと、スケール出来ない設計になってしまう
Node.js 以外でも
ある程度は課金で解決できることもある
‘

バージョン間の互換性が高い
* Node.js の API 自体は安定している
* しかしバージョンアップしたら意外と動かなくなる
(パフォーマンス劣化/メモリリークしていることも)
* 拡張ライブラリは全く動かなくなる場合もある
‘

サーバを API 化すれば、

JSON を返すだけのサーバで
OK
* ドメインロジックの管理のしやすさは
ライブラリに依存する
* サーバのデータをすべてクライアントに送れない
場合が多々あるので、その制御が必要
* OAuth の認証トークン
* 行動履歴
* ...
‘

リアルタイム通信
=
Socket.IO
リアルタイム通信の手段はたくさんある
* WebSocket
* Server-Sent Events
* XHR polling
* Socket.IO
* Pusher
...
リアルタイムを扱わない部分とのバランス
も考慮に入れる必要がある
まとめ
実際はこれに運用周りの話が加わってくるので、
もっと複雑
サービスの性質、規模やパフォーマンスによって、
落とし所はまた違ってくる
Node.js は大変素晴らしいけど、
適切に選択する必要がある
Node.js 以外の文化も踏まえた上で
Node.js を選択できると選択の幅が広がるのでは

いざというときに移行する判断ができるのも大事
で、これは常に変わっていくので、
バランスを見極めながら選択するんですかねー

* エコシステム
* ライブラリ
* 自分の作ろうとしているもの

答えはない
for more information...
静的サイト開発ツールとしての
MiddlemanとGrunt
http://webtech-walker.com/archive/2013/09/middleman_vs_grunt.html
Node.jsをサーバサイドの
UIレイヤに限定するのか?
http://wazanova.jp/post/63449778024/node-js-ui
ダブルMVCの意味するところ
[GoGaRuCo 2013]
http://wazanova.jp/post/64057743910/mvc-gogaruco-2013
http://www.flickr.com/photos/sakura-kame/479871795/

快適なweb開発を!

Node.js を選ぶとき 選ばないとき