node.jsをnvm(NodeersionManager)を使ってインストールし、パッケージ管理(npm)を使ってexpress環境を構築してみる。環境は以下の通り。 OS:CentOS6.5(x64) nvm:0.24.0 node.js:0.12.0 npm: forever: express:4.12.2
0.環境準備~nvm/node.jsのインストール
$ sudo useradd nodejs
$ sudo su - nodejs
$ sudo yum install git #入っていなかったら入れる
$ git clone git://github.com/creationix/nvm.git ~/.nvm
$ source ~/.nvm/nvm.sh
これでnvmはインストール完了。次はnvmを使ってnode.jsをインストールしてみる。
インストールできる、node.jsのバージョン一覧を確認する。偶数が安定板、奇数が開発版
$ nvm ls-remote
v0.1.14
v0.1.15
v0.1.16
・
・
・
・
v0.11.14
v0.11.15
v0.11.16
v0.12.0
$
ということで最新(2015/3/8 時点:v0.12.0)を入れてみることに。
$ nvm install 0.12.0
######################################################################## 100.0%
Now using node v0.12.0
とても簡単!完了。次に複数インストールした場合のデフォルトで使用するバージョンを設定しておく
$ nvm alias default v0.12.0
default -> v0.12.0
デフォルトでnvmも使えるように設定する
$ vi ~/.bash_profile
・
・
if [[ -f ~/.nvm/nvm.sh ]];
then source ~/.nvm/nvm.sh
npm_dir=${NVM_PATH}_modules
export NODE_PATH=$npm_dir
export PATH=$NVM_BIN:$PATH
fi
次にnode.jsのサンプルを作成してみる
$ vi example.js
var http = require('http');
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World\n');
}).listen(9000, "192.168.0.74");
console.log('Server running at http://192.168.0.74:9000/');
実行!
$ node example.js
Server running at http://192.168.0.74:9000/
超簡単・・。ブラウザで表示。
ただこの状態だと、エラーがあるとプロセスがこけてしまい、Webサーバーがダウンすることになる。 試しに、以下のようなサンプルコードを実行した場合、
$ vi example_err.js
var n = 0;
var http = require('http');
http.createServer(function (req, res) {
if (++n > 4) { a }
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end("result:" + n + "\n");
}).listen(9000, "192.168.0.74");
console.log('Server running at http://192.168.0.74:9000/');
別端末でcurlでアクセスをしてみると、変数"n"がカウントアップされ、5回目に変数"a"を参照しにいき、落ちる。
$ curl http://192.168.0.74:9000
result:1
$ curl http://192.168.0.74:9000
result:2
$ curl http://192.168.0.74:9000
result:3
$ curl http://192.168.0.74:9000
result:4
$ curl http://192.168.0.74:9000
url: (52) Empty reply from server
node.js側はこんな感じ。
$ node example_err.js
Server running at http://192.168.0.74:9000/
/home/nodejs/example_err.js:4
if (++n > 4) { a }
^
ReferenceError: a is not defined
at Server.<anonymous> (/home/nodejs/example_err.js:4:18)
at Server.emit (events.js:110:17)
at HTTPParser.parserOnIncoming [as onIncoming] (_http_server.js:491:12)
at HTTPParser.parserOnHeadersComplete (_http_common.js:111:23)
at Socket.socketOnData (_http_server.js:343:22)
at Socket.emit (events.js:107:17)
at readableAddChunk (_stream_readable.js:163:16)
at Socket.Readable.push (_stream_readable.js:126:10)
at TCP.onread (net.js:529:20)
これだと実際には使えない・・・ということで、次にnpmを使ってforeverというモジュールを使ってみる。
1.npmを使ってforeverをインストールしてみる
node.jsを入れると、npmもインストールされている。これを使って、foreverモジュールをインストールしてみる。
$ npm install -g forever
"-g"でグローバルインストールとし、全部のアプリで使えるようにしておく。 インストールが終わったら、実際に実行してみる。
$ npm
Usage: npm <command></command>
where <command></command> is one of:
add-user, adduser, apihelp, author, bin, bugs, c, cache,
completion, config, ddp, dedupe, deprecate, docs, edit,
explore, faq, find, find-dupes, get, help, help-search,
home, i, info, init, install, issues, la, link, list, ll,
ln, login, ls, outdated, owner, pack, prefix, prune,
publish, r, rb, rebuild, remove, repo, restart, rm, root,
run-script, s, se, search, set, show, shrinkwrap, star,
stars, start, stop, t, tag, test, tst, un, uninstall,
unlink, unpublish, unstar, up, update, v, verison, version,
view, whoami
npm <cmd> -h quick help on <cmd>
npm -l display full usage info
npm faq commonly asked questions
npm help <term> search for help on <term>
npm help npm involved overview
Specify configs in the ini-formatted file:
/home/nave/.npmrc
or on the command line via: npm <command></command> --key value
Config info can be viewed via: npm help config
npm@2.1.14 /usr/local/nave/installed/0.10.35/lib/node_modules/npm
$ forever start example_err.js
warn: --minUptime not set. Defaulting to: 1000ms
warn: --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms
info: Forever processing file: example_err.js
warningはでたけど、、起動している。先ほどのようにcurlで何度かアクセスすると、resultが1に戻って表示され node.js側は何もエラーがでていない。つまり、node.jsが再起動されて起動し続けているということのようです。 一件落着。
で次に、expressだ。
2.npmを使ってexpressをインストールしてみる
これを使ってexpressをインストールする。
$ npm install -g express
express@4.12.2 /home/nodejs/.nvm/versions/node/v0.12.0/lib/node_modules/express
tqq merge-descriptors@1.0.0
tqq utils-merge@1.0.0
tqq cookie-signature@1.0.6
tqq methods@1.1.1
tqq fresh@0.2.4
tqq cookie@0.1.2
tqq escape-html@1.0.1
tqq range-parser@1.0.2
tqq content-type@1.0.1
tqq finalhandler@0.3.3
tqq vary@1.0.0
tqq parseurl@1.3.0
tqq serve-static@1.9.1
tqq content-disposition@0.5.0
tqq path-to-regexp@0.1.3
tqq depd@1.0.0
tqq on-finished@2.2.0 (ee-first@1.1.0)
tqq qs@2.3.3
tqq etag@1.5.1 (crc@3.2.1)
tqq proxy-addr@1.0.6 (forwarded@0.1.0, ipaddr.js@0.1.8)
tqq debug@2.1.2 (ms@0.7.0)
tqq send@0.12.1 (destroy@1.0.3, ms@0.7.0, mime@1.3.4)
tqq type-is@1.6.0 (media-typer@0.3.0, mime-types@2.0.9)
mqq accepts@1.2.4 (negotiator@0.5.1, mime-types@2.0.9)
インストール完了・・これまたあっけなし。以下のサンプルプログラムでお試し。
$ vi app.js
var express = require('express');
var app = express();
app.get('/',function (req,res){
res.send('Hello Express!');
});
app.listen(9000,"192.168.0.74");
ブラウザでつついて、ばっちり!あとは追加でexpressのひな形自動作成ツールを追加してみる。
express-generatorというパッケージになる。
$ npm install -g express-generator
/home/nodejs/.nvm/versions/node/v0.12.0/bin/express -> /home/nodejs/.nvm/versions/node/v0.12.0/lib/node_modules/express-generator/bin/express
express-generator@4.12.1 /home/nodejs/.nvm/versions/node/v0.12.0/lib/node_modules/express-generator
tqq sorted-object@1.0.0
tqq commander@2.6.0
mqq mkdirp@0.5.0 (minimist@0.0.8)
次にEJSというビューテンプレートを使ってひな形を作成してみる。
$ express --ejs expressexample
create : expressexample
create : expressexample/package.json
create : expressexample/app.js
create : expressexample/public
create : expressexample/public/javascripts
create : expressexample/public/images
create : expressexample/public/stylesheets
create : expressexample/public/stylesheets/style.css
create : expressexample/routes
create : expressexample/routes/index.js
create : expressexample/routes/users.js
create : expressexample/views
create : expressexample/views/index.ejs
create : expressexample/views/error.ejs
create : expressexample/bin
create : expressexample/bin/www
install dependencies:
$ cd expressexample && npm install
run the app:
$ DEBUG=expressexample:* ./bin/www
で作成。ただこれだけだとディレクトリ・ファイルが出来上がっただけなので、記載されいてるとおり、
$ cd expressexample && npm install
でセットアップする。出来上がったものを、これまた記載通りDEBUG付きで実行してみる。
$ DEBUG=expressexample:* ./bin/www
expressexample:server Listening on port 3000 +0ms
あとはブラウザでアクセスしてみると、ばらばらとデバッグ(トレース)が出てきた。なるへそねぇ。
で、もう少し出来上がった中身を見てみる。
$ vi package.json
{
"name": "expressexample",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"body-parser": "~1.12.0",
"cookie-parser": "~1.3.4",
"debug": "~2.1.1",
"ejs": "~2.3.1",
"express": "~4.12.2",
"morgan": "~1.5.1",
"serve-favicon": "~2.2.0"
}
}
これはnpmのファイル。6行目の内容は、npm startと打った時に実行される内容。
つまり、
$ npm start
でも実行ができるということですね。あとは依存関係のあるパッケージが記載されている。このpackage.jsonファイル
を他の環境に持っていき、npm installをすれば、同じ環境が出来上がる!ということですね。
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes/index'); //(*1)
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes); //(*2)
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
このファイルは、サーバーで使用するミドルウェアを取り込んだり、ルーティングするためのファイルとのこと。
例えば(*2)は
http://192.168.0.74/
でアクセスされた場合のルーティング設定で、この行ではroutes変数にアサインされている。で、routes変数に何が入っているかというと、、(*1)に記載されている。
(*1)ではroutes変数に[./routes/index]を割り当てているが、これは./routes/index.jsのことを指している。
ちなみに、このapp.jsファイルを読むと、ルーティングはファイルの上から順に評価されていき、該当したところで止まる(後続は処理されない)という処理のようですね。今後作っていく際のポイントになりそう。
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;
このファイルは上記にあったapp.jsで呼び出されたroutes/index.js。ポイントは6行目。今回テンプレートとしてejsを採用しているので、この行にあるrender関数でejsテンプレートが呼び出される。どのテンプレートかというと、第一引数がindexとなっているので、views/index.ejsだ。このテンプレートを呼び出すにあたり、title変数に、[Express]を設定して、呼び出している。
$ vi views/index.ejs
<html>
<head>
<title><%= title %></title>
<link href="/stylesheets/style.css" rel="stylesheet"></link>
</head>
<body>
<h1><%= title %></h1>
Welcome to <%= title %>
</body>
</html>
このファイルはhtmlベースのテンプレートとなっており、<%= title %>となっているところに、index.jsのrender関数で指定したtitle編巣の値をセットしている。
今日はここまで・・