簡単なWebアプリを作る機会があったので、Node.js + Express入門してみた。
Node.jsとnpmインストール
nodebrewを入れる。
$ curl -L git.io/nodebrew | perl - setup
.bash_profile等にパスを追加
export PATH=$HOME/.nodebrew/current/bin:$PATH
$ nodebrew -v
nodebrew 0.9.6
$ nodebrew ls
v4.6.2
v6.9.1
v7.1.0
current: nonde
$ nodebrew use v6.9.1
$ nodebrew ls
v4.6.2
v6.9.1
v7.1.0
current: v6.9.1
$ npm -v
3.10.8
Expressインストール
npmで簡単に導入
$ npm install -g express
ただ、プロジェクト作るときにはexpress-generatorがあるとより簡単なのでこれも入れる
$ npm install -g express-generator
Expressプロジェクトを作成
express-generatorによりプロジェクトが生成される。
使い方はrailsのgenerateと似たような感じ。
テンプレートエンジンをjadeにしたい場合は、warningで--view=jadeを指定するように怒られているが今回はそのままスルー。将来的にデフォルトでなくなるらしい。
$ express sampleapp
warning: the default view engine will not be jade in future releases
warning: use `--view=jade' or `--help' for additional options
create : sampleapp
create : sampleapp/package.json
create : sampleapp/app.js
create : sampleapp/public
create : sampleapp/public/javascripts
create : sampleapp/public/images
create : sampleapp/routes
create : sampleapp/routes/index.js
create : sampleapp/routes/users.js
create : sampleapp/public/stylesheets
create : sampleapp/public/stylesheets/style.css
create : sampleapp/views
create : sampleapp/views/index.jade
create : sampleapp/views/layout.jade
create : sampleapp/views/error.jade
create : sampleapp/bin
create : sampleapp/bin/www
install dependencies:
$ cd sampleapp && npm install
run the app:
$ DEBUG=sampleapp:* npm start
依存モジュールのインストール
$ npm install
立ち上げてみる
Expressを起動してブラウザでアクセス(localhost:3000)
$ npm start
又は
$ node bin/www
構築完了。
もう少し細かく見てみる
app.jsとrouting
ここにアプリケーションに関する記述が入っている。
var index = require('./routes/index');
var users = require('./routes/users');
...
app.use('/', index);
app.use('/users', users);
このような記述があり、以下のように動く。
URLでdocument root ('/')にアクセスした時には、routes/index.jsが読み込まれそこに記述した処理が適用される。
routes/index.jsを見てみると以下のようになっており、GETが定義されている。
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
たとえばここに以下のように変えた場合、/hogehogeでアクセス出来る。
/* GET home page. */
router.get('/hogehoge', function(req, res, next) {
res.render('index', { title: 'Express' });
});
また、app.useの部分を以下のように変えると、違うパスにマウントされる感じで用意に切り替えることができるらしい。
こうすると、/hoge/hogehogeというパスでアクセスできるようになる。
var index = require('./routes/index');
var users = require('./routes/users');
...
// app.use('/', index); 以下のように変えてみる
app.use('/hoge', index);
app.use('/users', users);
app.useの他にも、app.getやapp.postで直接パスを指定できるが、拡張性などを考えるとapp.useとするのが便利そう。
npm foreverを使ってデーモン化
node bin/wwwの起動だと、コマンド終了するとサーバも停止してしまうため、foreverというものを使ってみる。
インストール
$ npm install forever -g
foreverを使って起動する
$ forever start bin/www
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: bin/www
$
この起動の場合は、ログファイル名は起動毎に変わり~/.forever/xxx.log
に出力される。
ログファイル名を指定する場合はオプションを付けて以下のようにする。
$ forever start -a -l app.log -e error.log bin/www
※-aを付けないと、次回起動時に下記のように怒られる
error: Cannot start forever
error: log file /xxxxxx/.forever/app.log exists. Use the -a or --append option to append log.
起動後の確認
$ forever list
info: Forever processes running
data: uid command script forever pid id logfile uptime
data: [0] FRen /Users/xxxxxx/.nodebrew/node/v6.9.1/bin/node bin/www 61131 61132 /Users/xxxxxx/.forever/FRen.log 0:0:0:18.592
$
プロセスが起動しているのが分かる。
停止するときは、
$ forever stop bin/www
info: Forever stopped process:
uid command script forever pid id logfile uptime
[0] FRen /Users/xxxxxx/.nodebrew/node/v6.9.1/bin/node bin/www 61131 61132 /Users/xxxxxx/.forever/FRen.log 0:0:1:42.953
環境の切り替え
起動時にNODE_ENVを指定することで、環境ごとの設定をする。
$ NODE_ENV=development forever start bin/www // 開発
$ NODE_ENV=stage forever start bin/www // ステージング
$ NODE_ENV=production forever start bin/www // 本番
あとはconfigのymlかなんかを作って、ENVを読み込めるようにする。
以下はdatabase接続を環境ごとに分ける例。
env:
development:
database:
host: localhost
port: 5432
user: localuser
password: localpass
stage:
database:
host: xxx.xxx.xx.xxx // DBサーバのIP
port: 5432
user: user1
password: xxxxx
production:
database:
host: yyy.yyy.yy.yyy // DBサーバのIP
port: 5432
user: user1
password: yyyyy
'use strict'
var jsYaml = require('js-yaml')
, fs = require('fs')
, yml = jsYaml.safeLoad(fs.readFileSync(__dirname + '/config.yml', 'utf8'))
;
exports.getEnvConfig = getEnvConfig;
function getEnvConfig() {
var currentEnv = process.env.NODE_ENV || 'production' // ここで起動時に設定したものを読み込む
;
return yml.env[currentEnv];
}
使う側の例
'use strict'
var options = {}
, config = require('../config/config')
, dbConfig = config.getConfig()['database']
, pgp = require("pg-promise")(options)
, connection = {}
, db = null
;
connection = {
host: dbConfig.host,
port: dbConfig.port,
database: 'db_name',
user: dbConfig.user,
password: dbConfig.password
};
db = pgp(connection);
module.exports = db;