Node.js インストールしてみた

いまさらながら Node.js をインストールしてみた。いまさらすぎて、世間に出てる記事の通りに書いても、仕様が変わったりバージョンが違ったりでうまく動かなかったので、現時点(2011/07/15)で動くようになったところまでのメモ。
OS: MacOSX 10.6.7

Node.js 本体のインストール

どうやらMacPortsに登録されているっぽいので、MacPorts経由でインストール。
まずは ports の更新から

$ sudo port selfupdate
$ sudo port upgrade outdated

んで、node 本体のインストール

$ sudo port install nodejs

ここで v0.4.9 がインストールされた。一応 which で確認。

$ which node
/opt/local/bin/node

動作確認

こんな感じのスクリプトを書いて hello.js で保存する。

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/');

そして、下記のコマンドでサーバー起動。

$ node hello.js  # ちなみに、 "node hello" みたいに拡張子なしでも動くっぽい
Server running at http://127.0.0.1:1337/

これで、1337 ポートで待ち受けることに成功。ブラウザで http://127.0.0.1:1337/ にアクセスして "Hello World" が表示されたら成功。終了は Ctrl+C で。


パッケージの導入

このへんが一番はまった。
どうやら npm っていうパッケージ管理コマンドをインストールするのに、nodejs が 0.4.1 以下じゃないとインストールできないと言われる。なので、nave という、nodejs の実行環境を切り替えられるパッケージをまず導入する。


nave のインストール
$ git clone http://github.com/isaacs/nave.git

このとき、nave ディレクトリの中にある nave.sh にパスを通しておくと楽。自分は /usr/local/src に展開して /usr/local/bin にシンボリックリンクをおいた。

$ sudo ln -s /usr/local/src/nave.sh /usr/local/bin/nave

この nave というコマンドは nodejs のバージョンの管理をしてくれる。例えば、最新の nodejs を使いたい場合は

$ nave install latest
$ nave use latest

とやると、今後 node コマンドを使用したときはその時の最新バージョン(今回は 0.5.0 あれ・・・、stableは0.4.9じゃないん・・・?)が使用される。
さて、今回は npm のインストールに 0.4.1 以下である必要があったので、0.4.1 を導入する。

$ nave install 0.4.1
$ nave use 0.4.1

これで、きっと nodejs のバージョンは 0.4.1 が使われるはず。ちょっと確認。

$ node -v
v0.4.1

うん、OKですね。


npm のインストール

そのへんのブログとか記事とかのとおり、

$ curl http://npmjs.org/install.sh | sh

ってやっても sudo つけても自分の環境では動かなかったので、段階的にやってみた。
まずは install.sh をダウンロードする

$ wget http://npmjs.org/install.sh

権限みてみる。

$ ls -l install.sh
-rw-r--r--  1 root      staff  3902  7  7 10:03 install.sh

実行できなさそう。権限変更する。ローカル環境だし、777でいいかな。

$ sudo chmod 777 install.sh

それで実行してみる。

$ ./install.sh
fetching: http://registry.npmjs.org/npm/-/npm-1.0.15.tgz
0.4.1
1.0.15
prefix=/Users/katsuren/.nave/installed/0.4.1

This script will find and eliminate any shims, symbolic
links, and other cruft that was installed by npm 0.x.

Is this OK? enter 'yes' or 'no' 
yes

All clean!
! [ -d .git ] || git submodule update --init
node cli.js cache clean
node cli.js rm npm -g -f --loglevel error
node cli.js install -g -f
npm ERR! Could not create /Users/hoge/.nave/installed/0.4.1/lib/node_modules/___npm.npm
npm ERR! error installing npm@1.0.15 Error: EACCES, Permission denied '/Users/hoge/.nave/installed/0.4.1/lib/node_modules'
npm ERR! Error: EACCES, Permission denied '/Users/hoge/.nave/installed/0.4.1/lib/node_modules'
npm ERR! 
npm ERR! Please use 'sudo' or log in as root to run this command.
npm ERR! 
npm ERR!     sudo npm "install" "-g" "-f"
npm ERR! 
npm ERR! or set the 'unsafe-perm' config var to true.
npm ERR! 
npm ERR!     npm config set unsafe-perm true
npm ERR! 
npm ERR! System Darwin 10.7.4
npm ERR! command "node" "/private/var/folders/QJ/QJ8FnYySGnyW-huwb0AqP++++TI/-Tmp-/npm.87904/package/cli.js" "install" "-g" "-f"
npm ERR! 
npm ERR! Additional logging details can be found in:
npm ERR!     /private/var/folders/QJ/QJ8FnYySGnyW-huwb0AqP++++TI/-Tmp-/npm.87904/package/npm-debug.log
npm not ok
make: *** [install] Error 13
npm WARN Not installed in /Users/hoge/.nave/installed/0.4.1/lib/node_modules npm
npm ERR! Could not create /Users/hoge/.nave/installed/0.4.1/lib/node_modules/___npm.npm
npm ERR! error installing npm@1.0.15 Error: EACCES, Permission denied '/Users/hoge/.nave/installed/0.4.1/lib/node_modules'
npm ERR! Error: EACCES, Permission denied '/Users/hoge/.nave/installed/0.4.1/lib/node_modules'
npm ERR! 
npm ERR! Please use 'sudo' or log in as root to run this command.
npm ERR! 
npm ERR!     sudo npm "install" "." "--force" "--global"
npm ERR! 
npm ERR! or set the 'unsafe-perm' config var to true.
npm ERR! 
npm ERR!     npm config set unsafe-perm true
npm ERR! 
npm ERR! System Darwin 10.7.4
npm ERR! command "/Users/hoge/.nave/installed/0.4.1/bin/node" "/private/var/folders/QJ/QJ8FnYySGnyW-huwb0AqP++++TI/-Tmp-/npm.87904/package/cli.js" "install" "." "--force" "--global"
npm ERR! 
npm ERR! Additional logging details can be found in:
npm ERR!     /private/var/folders/QJ/QJ8FnYySGnyW-huwb0AqP++++TI/-Tmp-/npm.87904/package/npm-debug.log
npm not ok
It failed

んー、なんかパーミッションがおかしいらしい。sudoつけちゃえ。

$ sudo ./install.sh
fetching: http://registry.npmjs.org/npm/-/npm-1.0.15.tgz
0.4.1
1.0.15
prefix=/Users/hoge/.nave/installed/0.4.1

This script will find and eliminate any shims, symbolic
links, and other cruft that was installed by npm 0.x.

Is this OK? enter 'yes' or 'no' 
yes 

All clean!
! [ -d .git ] || git submodule update --init
node cli.js cache clean
node cli.js rm npm -g -f --loglevel error
node cli.js install -g -f
/Users/hoge/.nave/installed/0.4.1/bin/npm -> /Users/hoge/.nave/installed/0.4.1/lib/node_modules/npm/bin/npm.js
/Users/hoge/.nave/installed/0.4.1/bin/npm-g -> /Users/hoge/.nave/installed/0.4.1/lib/node_modules/npm/bin/npm.js
/Users/hoge/.nave/installed/0.4.1/bin/npm_g -> /Users/hoge/.nave/installed/0.4.1/lib/node_modules/npm/bin/npm.js
npm@1.0.15 /Users/hoge/.nave/installed/0.4.1/lib/node_modules/npm 
It worked

お、ちゃんと入りましたね。一応確認

$ which npm
/Users/hoge/.nave/installed/0.4.1/bin/npm
$ npm -v
1.0.15

npm のバージョンは 1.0.15 ですね。


パッケージのインストール

とにもかくにも、俺は WebSocket が使いたいんじゃあああ!!!ということで、Socket.io を入れる。ついでに express も。

$ npm install socket.io
socket.io@0.7.7 ./node_modules/socket.io 
├── policyfile@0.0.3
├── redis@0.6.0
└── socket.io-client@0.7.4
$ npm install express
express@2.4.3 ./node_modules/express 
├── mime@1.2.2
├── qs@0.2.0
└── connect@1.6.0
動作確認

とりあえず、require した時点でエラーがでてないか確認する。test.js に下記のソースを書く。

var io = require('socket.io');
var express = require('express');

動かす。

$ node test.js

ここで、エラー吐いて落ちるようであれば、インストールに失敗している。


懸念点

ここで、npm 使ってパッケージをインストールしたら、npm 使ったカレントディレクトリに "node_modules" っていうディレクトリができて、そこにパッケージがインストールされちゃうらしい。nave つかってるからだと思うんだけど、このへんをうまく解決できなかった。別に設定ファイルかなんかがあるのかな。



パッケージを使ってみる。

node.jsはじめました - KAYAC engineers' blog
このへんのソースを参考にやって見た。
この記事が書かれた当初からバージョンが変わってるっぽくて、いろいろ動かなかった。ソース自体は記事を参考にしてもらうとして、変更した箇所だけ抜粋する。
GitHub - socketio/socket.io: Realtime application framework (Node.JS server)
このへんに Socket.io のバージョン 0.6 -> 0.7 の変更点もあったので、参考にした。

まずはサーバー側。ソケットの扱いが変わってるっぽいので、編集。

var io = require('socket.io');
var socket = io.listen(app);
socket.on('connection', function(client) {
    client.on('message', function(msg) {
        client.send(msg);
        client.broadcast(msg);
    });
});

var io = require('socket.io').listen(app);
io.sockets.on('connection', function(client) {
    client.on('message', function(msg) {
    	client.broadcast.emit('message', msg);
    });
});

そしてクライアント側。

var socket = new io.Socket();
socket.on('message', function(msg) {
  var div = document.createElement('div');
  div.appendChild(document.createTextNode(msg));
  document.body.appendChild(div);
});
socket.connect();

var socket = new io.connect();
socket.on('message', function(msg) {
  var div = document.createElement('div');
  div.appendChild(document.createTextNode(msg));
  document.body.appendChild(div);
});

こんな感じで動くようになった。