Post on 02-Dec-2014
description
佐藤 竜之介(Ryunosuke SATO)Sapporo.js東京Node学園祭 2013
Node.js を選ぶとき選ばないとき
2013.10.26
提供
Sapporo.js
Community for people who like JavaScript.
自己紹介
@tricknotesI am a software developer who love JavaScript and Ruby.
http://tricknotes.hateblo.jp/
I love OSS
I am a contributerof Ember.js
/* * advertising * * !!Important!! *
2013.11.30JavaScript 道場http://connpass.com/event/3674/
2013.11.30JavaScript 道場http://connpass.com/event/3674/in 札幌
*/
よろしくお願いします
佐藤 竜之介(Ryunosuke SATO)Sapporo.js東京Node学園祭 2013
Node.js を選ぶとき選ばないとき
2013.10.26
今日の話
私が “web アプリケーション” を作るときに、Node.js を選んだ場面、選ばなかった場面があります
そのときの背景を交えつつ、 Node.js と Rails を比較し Node.js の適切な使い所について考察
します
Why Rails?
Node.js ライブラリには Ruby / Rails の影響を受けているものが多い
なので、有意義な比較ができそう
* Rails(generator)<-> yeoman* Sinatra <-> Express* Sprockets <-> Mincer* Rails <-> Sails
対象者
* Node.js 以外の選択肢を知らない方* Node.js をあまり使ったことがない方
注意
早く快適にアプリケーションを開発する、ということに主眼を置いて考察していきます
パフォーマンスやサーバリソースなどの優先順位は低めです
さて、みなさんが “web アプリケーション” を作りはじめるとき、どういう基準でその手段を選ぶでしょうか?
Node.js の場合
Node.js での web アプリケーション開発について確認してみましょう
まずは素の状態で始めてみる
var http = require('http');
http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n');}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
$ curl http://localhost:1337Hello World
Node.js の基本的な仕組みを理解するには大事な一歩
でも、これだけだとまだまだ簡単には作れそうにない
実際にはもっと複雑なアプリケーションを作ることになるでしょう
複雑さに立向うためにライブラリを使う
例えば、 express を使ってみる
var express = require('express');var app = express();
app.get('/', function(req, res){ res.send('Hello World');});
app.listen(3000);
express はとてもシンプル
コアが大きくないし、拡張も簡単
ただ、自由度が高いために整理するのに工夫が必要
確かに、express だと、学習コストは低いかもしれない
学習コスト?開発速度を維持するコスト?
どっちが大事?
もうすこし大きなフレームワークを好むひともいるかもしれない
データベースとつなげればいいんじゃなくて、ドメインロジックの管理も適切に行いたい...!!
model 周りが貧弱* 関連を扱えない
* マイグレーションがない
そこまで大きな手助けしてくれるフレームワークではないのでは...?
最初に大長編 Gruntfile.js を生成する
デフォルトで上手いことやってほしい
生成されたコードはバージョンアップに追従するのが面倒
contlib で様々なタスクが配布されているのはありがたい
but...
設定を毎回書くのは手間
grunt.loadNpmTasks('grunt-contrib-coffee');
grunt.initConfig({ coffee: { compile: { files: { 'result.js': 'source.coffee' } } } });
もっと、スムーズに開発を進めたい...!!
Rails の場合
* CoffeeScript や Sass のコンパイル* asset ファイルの minify, concat* digest hash の付与
Grunt 使ってやりたくなるようなことは、デフォルトでやってくれる
Asset pipeline
Asset pipeline
//= require jquery//= require underscore////= require app
* application.js
application.js にリクエストを投げると、すべて連結して取得できる
ビルド時には minify + digest が付与される
ビルドタスク
そもそもデフォルトで入っている
$ rake asset:precompile
* jquery-rails* underscore-rails* moment-rails ...
assets のパスが追加される、だけ静的なファイルをリポジトリに含めなくてOK
js のライブラリの管理
* validation* relation* migration* ドメインロジックの管理
ActiveRecord
一本の道があるということの良い所
その道に沿うように他のライブラリが成長していく
Rails に乗る形で、まとまった単位の機能を提供するライブラリが多い
* 画像アップロード -> carrierwave* 認証管理 -> devise* OAuth provider -> doorkeeper
やりたいことを実現するまでの手数が少ない
ちょっと基本に立ち返る
そもそも、Node.js と Rails ではスタートが違う
“Evented I/O for V8 javascript.”
あくまで、非同期 IO の環境
web 開発以外でも活躍している
https://github.com/rogerwang/node-webkit
“Web development that does’t hurt”
web 開発のためのフレームワーク
7 年かけて環境が整備されてきている
言語(仕様)
言語(実装)
ライブラリ
フレームワーク
Rails が開発効率に重点を置いているので、使いやすいのは納得できる
Node.js では、まだその大きさのフレームワークは出てきてなくて、 小回りが効くライ
ブラリが多い
Node.js にも、 道を敷いてくれるようなフレームワークがあるとよいの...?
そうでもない、ような...
私の例
自分の例①
->
NotHub
* GitHub のイベントをリアルタイムに通知する Chrome Extension* 受け取るイベントを設定可能* public なリポジトリ限定
よくある使い方
* ライブラリのバージョンアップを早く知りたい* 自分のリポジトリが star されたのを知りたい* 興味があるハッカーの活動を知りたい
Crawler
GitHub API
Chrome Extension
Publisher
Redis
crawlPub
Sub
最初は Ruby で書き始めたが、パフォーマンスでなくて Node.js で書き直した
* GitHub の API をとにかく叩く必要があった* Ruby でマルチスレッド処理するのは意外と面倒* Ruby で非同期書くのも手間
そもそも、Rails が得意な分野ではない
通知の部分は単純な push 通知なので、 Socket.IO がフィットした
当時は Grunt の開発が始まったばかりChrome Extension をパッケージしたい
ビルドタスクは Rake
今だと Grunt を使うかも
自分の例②
->
* GitHub の followings の star を daily メールでお知らせする web アプリ* リアルタイムじゃなくてアーカイブ
starseeker
* 良さそうなライブラリを知る手がかりに!!* 朝、仕事を始める前に hot なリポジトリをチェック
よくある使い方
GitHub API
Crawler
Web Application
MongoDB
PostgreSQL
crawlsave
read
* Crawl したデータを MongoDB へ* MongoDB なら Node.js と思って書き始めたが...* ユーザ管理とか OAuth 周りが意外と面倒* Rails でやることに
Crawl する部分は Node.js
メール配信も、Rails がいい感じにフィットした
* html/text の multipart メール* html とのコード共有
両方ともそれぞれに良さがあるので、それぞれに適切な場面がある!!
<->
よくある誤解集
これだけで選択するのはまだ早い
‘‘クライアントとサーバの言語統一できて開発がはかどる
* DOM を扱う JavaScript と、ネットワーク、 ドメインロジックを扱う JavaScript は違う* 確かに言語は統一できるけど、思考の スイッチングコストは発生する
// DOMjQuery('form').trigger(‘form’);
// Node.jsstream.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...
http://webtech-walker.com/archive/2013/09/middleman_vs_grunt.html
静的サイト開発ツールとしてのMiddlemanとGrunt
http://wazanova.jp/post/63449778024/node-js-ui
Node.jsをサーバサイドのUIレイヤに限定するのか?
http://wazanova.jp/post/64057743910/mvc-gogaruco-2013
ダブルMVCの意味するところ [GoGaRuCo 2013]
http://www.flickr.com/photos/sakura-kame/479871795/
快適なweb開発を!