Hatena::ブログ(Diary)

ursmの日記

2010-09-25

node.js を試してみた

凄いという噂は耳にするものの、何なのかよくわからない node.js を試してみました。

イベント駆動かつ非同期 I/O なアーキテクチャのサーバサイド JavaScript 処理系で、リソースの消費を抑えつつも高いパフォーマンスを実現するものと理解しましたがあってるんでしょうか。

インストール

GitHub - monoid/gentoo-nodejs: This overlay is not maintained anymore.

私は Gentoo 使いなので、ここの overlay から emerge しました。

% layman -f -o http://github.com/downloads/monoid/gentoo-nodejs/nodejs-layman.xml -a nodejs
% emerge -av nodejs

hello, world

公式サイトのサンプルをそのまま写経します。

// example.js
var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(8124, "127.0.0.1");
console.log('Server running at http://127.0.0.1:8124/');
% node example.js 
Server running at http://127.0.0.1:8124/
% curl localhost:8124
Hello World

Rack を生で使ってる感じですね。

npm (Node Package Manager)

RubyGems みたいなやつです。

まず ~/.npmrc を作成します。

root = /home/ursm/.npm/libraries
binroot = /home/ursm/.npm/bin
manroot = /home/ursm/.npm/man

.bashrc などで環境変数を設定します。

export NODE_PATH=/home/ursm/.npm/libraries:$NODE_PATH
export PATH=/home/ursm/.npm/bin:$PATH
export MANPATH=/home/ursm/.npm/man:$MANPATH

インストールスクリプトを走らせます。

% curl http://npmjs.org/install.sh | sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   338  100   338    0     0    502      0 --:--:-- --:--:-- --:--:--  1640
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  568k  100  568k    0     0   186k      0  0:00:03  0:00:03 --:--:--  400k
node cli.js cache clean
npm info it worked if it ends with ok
npm info version 0.2.2
npm ok
node cli.js rm npm
npm info it worked if it ends with ok
npm info version 0.2.2
npm info not installed npm
npm ok
node cli.js install npm
npm info it worked if it ends with ok
npm info version 0.2.2
npm info fetch http://registry.npmjs.org/npm/-/npm@0.2.2.tgz
npm info install npm@0.2.2
npm info activate npm@0.2.2
npm info build Success: npm@0.2.2
npm ok
It worked

入りました。node.js 界隈はインストール方法が curl ... | sh のものが多くて怖いです。

この npm というやつ、man を見てもコマンド一覧すら載っていません。とりあえずパッケージのインストールは npm install のようです。

% npm install express
npm info it worked if it ends with ok
npm info version 0.2.2
npm info fetch http://registry.npmjs.org/express/-/express-1.0.0rc3.tgz
npm info install express@1.0.0rc3
npm info activate express@1.0.0rc3
npm info build Success: express@1.0.0rc3
npm ok

npm ls で全パッケージの一覧を表示、検索はまだないみたいですnpm ls pkgname でパッケージ名から検索できます。

CoffeeScript

いきなり脇道に入りますが、JavaScript の文法ってどうも好きになれません。括弧を省略できないのとセミコロンと function() が長すぎるのが駄目みたいです。

Ruby/Python っぽい記法から JavaScript を生成する CoffeeScript というものを試してみます。

% npm install coffee-script

先ほどのサンプルを CoffeeScript に書き直してみます。

# example.coffee
http = require('http')
http.createServer (req, res) ->
  res.writeHead 200, 'Content-Type': 'text/plain'
  res.end 'Hello World\n'
.listen 8124, "127.0.0.1"
console.log 'Server running at http://127.0.0.1:8124/'

こんなふうに変換されます。

% coffee -p example.coffee 
(function() {
  var http;
  http = require('http');
  http.createServer(function(req, res) {
    res.writeHead(200, {
      'Content-Type': 'text/plain'
    });
    return res.end('Hello World\n');
  }).listen(8124, "127.0.0.1");
  console.log('Server running at http://127.0.0.1:8124/');
}).call(this);

coffee コマンドで直接実行できます。

% coffee example.coffee
Server running at http://127.0.0.1:8124/

文字列中の式展開や可変長引数のサポートもあっていい感じです。

Express

Express というフレームワークを使ってみます。Sinatra によく似ています。

% npm install express

Express は Connect というフレームワークに依存しています。Connect は Rack middleware のような仕組みを実現するためのものみたいです。

express = require('express')
app = express.createServer()

app.get '/', (req, res) ->
  res.send 'Hello World\n'

app.listen 8124

素晴らしいことに Haml が使えます。hamlhamljs があって紛らわしいのですが、Express がデフォルトで対応しているのは haml の方です。

% npm install haml
express = require('express')
app = express.createServer()

app.configure ->
  app.set 'view engine', 'haml'

app.get '/', (req, res) ->
  res.render 'index', layout: false, locals:
    message: 'hello, world'

app.listen 8124
-# views/index.haml

%h1 hello
%p&= message

layout: false にしないと layout.haml がないときエラーになります。いけてませんね。locals はあるものの、インスタンス変数に相当するものがないので毎回すべての変数を渡さないといけません。content_for がないのもかなり痛いです。

この Haml あまり出来がよくなくて、コメントがコメントとして機能していません。後で hamljs を試してみます。

Spark

listen するポートがコードにベタ書きしてあるのは嫌ですね。rackup みたいなものはないかと探していたら、ありました。

% npm install spark

spark で起動できるようにするには「app.jshttp.Server または net.Server のインスタンスをエクスポート」すればいいらしいです。

つまりこういうことみたいです。

# app.coffee
express = require('express')
app = module.exports = express.createServer()

app.configure ->
  app.set 'view engine', 'haml'

app.get '/', (req, res) ->
  res.render 'index', layout: false, locals:
    message: 'hello, world'

あるファイルが require() されたとき、module.exports に設定されたオブジェクトが返ります。これは CommonJS という仕様の仕組みだそうです (参考: Server-side JavaScript と CommonJS - 廃墟)。

このファイルは .js じゃなくて .coffee なので、spark で起動するにはちょっと小細工しないといけません。

% spark app.coffee --eval "require('coffee-script')"
Spark server(9596) listening on http://*:3000 in development mode

require('coffee-script') すると require().coffee を扱えるよう拡張されます。

spark を経由するとポート番号やワーカ数を設定できるようになります。

% spark -h
Usage: spark [options]

Options:
  --comment            Ignored, this is to label the process in htop
  -H, --host ADDR      Host address, defaults to INADDR_ANY
  -p, --port NUM       Port number, defaults to 3000
  --ssl-key PATH       SSL key file
  --ssl-crt PATH       SSL certificate file
  -n, --workers NUM    Number of worker processes to spawn
  -I, --include PATH   Unshift the given path to require.paths
  -E, --env NAME       Set environment, defaults to "development"
  -M, --mode NAME      Alias of -E, --env
  -e, --eval CODE      Evaluate the given string
  -C, --chdir PATH     Change to the given path
  -c, --config PATH    Load configuration module
  -u, --user ID|NAME   Change user with setuid()
  -g, --group ID|NAME  Change group with setgid()
  -v, --verbose        Enable verbose output
  -V, --version        Output spark version
  -K, --no-color       Suppress colored terminal output
  -h, --help           Outputy help information
  --ENV VAL            Sets the given spark environment variable

ただ残念なことに、先ほどの CoffeeScript 対応ハックを使うと複数ワーカの起動に失敗してしまいます。おそらく spawn したプロセスで --eval の内容が実行されていないのだと思いますが、直せそうだったら直してみたいものです。

長くなってきたので続きはまた今度。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証