入門編
Node.jsとはなにか?
公式サイト
https://nodejs.org/
API DOCS にNode.jsの標準モジュールの記載がある。
Stability Index を見るとその各命令が安定しているかどうかを確認することができる。
数値が高い方が安定している。
特徴
・大量のリクエストを高速でさばくことができる。(APIに向いている)
・メモリ消費量が少ない
・サーバ側、クライアント側で処理の共通化ができる
・サーバサイドのコード変更した場合、Node.jsアプリの再起動が必要
・Node.jsは、フレームワークではありません。ライブラリでもありません。
・JavaScript アプリケーションのプラットフォーム
スレッドモデルとイベントループ
PHPなどは、スレッドモデル(Apache)で処理されますが、node.jsはイベントループにて処理をしています。
スレッドモデル(Apache)
リクエスト毎にスレッドを立ち上げる。
スレッド毎にメモリを消費する。
メモリ上限があるので、スレッドを立ち上げる上限があり、これ以上のリクエストを処理できない。
イベントループ(node.js)
キューと実際に処理するスレッド(I/O)がある。
node.jsでは、リクエストがあるごとにキューにためる。
キューに処理が登録してある間は、イベントループを回して次々に処理を実際に処理するI/Oに渡す。
I/Oでは、前の処理終了を待たずに次々と処理を開始する。(このため処理の順番が不確定)
上記仕組みから、node.jsではノンブロッキングなコードの書き方をします。
コマンドラインからnodeを実行する方法
Node.js の実行方法
大きく分けて 2 つのやり方があります。
1 つはコマンドラインからnodeコマンドを実行する方法
2つ目は、ファイルとして実行する方法です。
コマンドラインからの実行
# node
これでnodeをインタラクティブに実行できるモードになります。
Hello Worldを出力させてみましょう。
>console.log('Hello World'); Hello World Undefined
ちなみに「.help」と打つと、いくつか使えるコマンドがあるので見ておくと良いでしょう。
# node > .help
.exitで抜けられます。
# node > .exit
node.jsのファイルを実行する方法
node.jsをファイルとして、実行する方法です。
以下のファイルを作成しておきましょう。
▼01.js
console.log("hello world");
nodeコマンドでファイルを指定して実行します。
# node 01.js hello world
node.jsでは、基本的にはノンブロッキングな書き方をします
ブロッキングな書き方とノンブロッキングな書き方
node.jsでは、基本的にはノンブロッキングな書き方をします。
ブロッキングな書き方
var start = new Date().getTime(); while(new Date().getTime() < start + 5000); console.log("hello world");
現在時刻から5秒間while文でループしています。この場合は、スレッドを専有するので他のリクエストを処理することができない。
ノンブロッキングな書き方
setTimeout(function(){ console.log('hoge2'); },3000); setTimeout(function(){ console.log('hoge1'); },1000);
この場合、1秒後にhoge1が出力されて、3秒後にhoge2が出力されます。
setTimeout関数は、指定した時間の後に非同期に実行してくれます。
時間がかかる処理は非同期関数を使って実装することをノンブロッキングな書き方といいます。
nodeでWebサーバーを作ってみよう
http モジュールを読み込んで createServer() すると nodeでWEBサーバを作成することができます。
▼webServer.js
// Node.js が用意しているhttp モジュールを読み込んでいます。 var http = require('http'); // webサーバを作成します。 var server = http.createServer(); // Serverオブジェクトを作成します。 server.on('request',function(req, res) { // HTTPレスポンスヘッダーを出力 res.writeHead(200,{'Content-Type': 'text/plain'}); // HTTPレスポンスボディを出力 res.write('helloworld !!'); // EOFを出力 res.end(); }); // webサーバの待ち受け開始 server.listen(3000,'182.50.xxxx.xxxx'); console.log("server listening ...");
これを実行します。
# node webServer.js { port:3000, host: '182.50.xxxx.xxxx' } server listening ...
さて、ブラウザでアクセスしてみましょう♪
https://182.50.xxxx.xxxx:3000
helloworld !!が出力されれば、正常に起動しています。
設定を外部ファイルに移して読み込む
以下の例では、sample.jsからsettings.jsを読み込み接続先の設定を取得しています。
外部ファイルには、 exports オブジェクトというものを使うのですが、「exports.」の後に変数や関数を定義してあげます。
exportsでオブジェクトを外部で使用可にして requireで呼び出す感じです。
exportsでは、変数だけではなくて、関数で使えます。
▼sample.js
// Node.js が用意しているhttp モジュールを読み込んでいます。 var http = require('http'); // この行を追加します。 var settings = require('./settings'); // webサーバを作成します。 var server = http.createServer(); // Serverオブジェクトを作成します。 server.on('request',function(req, res) { // HTTPレスポンスヘッダーを出力 res.writeHead(200,{'Content-Type': 'text/plain'}); // HTTPレスポンスボディを出力 res.write('helloworld !!'); // EOFを出力 res.end(); }); // webサーバの待ち受け開始 server.listen(settings.port, settings.host); console.log("server listening ...");
▼settings.js
exports.port = 3000; exports.host = '182.50.xx.xxx';
URLによって処理を変えてみよう
アクセスしてきた URL は req.url で取ることができます。その値を条件分岐に使用します。
▼sample.js
var http = require('http'); var settings = require('./settings'); var server = http.createServer(); var msg; server.on('request', function(req, res) { switch (req.url) { case '/about': msg = "about"; break; case '/profile': msg = " profile"; break; default: msg = "not found"; break; } res.writeHead(200, {'Content-Type': 'text/plain'}); res.write(msg); res.end(); }); server.listen(settings.port, settings.host); console.log("server listening ...");
▼settings.js
exports.port = 3000; exports.host = '182.50.xx.xxx';
HTMLファイルを読み込んでみよう
ファイルを読み込むにはファイルシステムのモジュールが必要になるので、「fs = require('fs');」とします。
ファイルを読み込むには fs.readFile() という命令をし、「__dirname」で今のディレクトリ名が取れます。
ファイルを読み込むのは時間がかかる処理なのでコールバック関数を使用します。
▼sample.js
var http = require('http'), fs = require('fs'); var settings = require('./settings'); var server = http.createServer(); var msg; server.on('request', function(req, res) { fs.readFile(__dirname + '/html/hello.html', 'utf-8', function(err, data) { if (err) { res.writeHead(404, {'Content-Type': 'text/plain'}); res.write("not found!"); return res.end(); } res.writeHead(200, {'Content-Type': 'text/html'}); res.write(data); res.end(); }); }); server.listen(settings.port, settings.host); console.log("server listening ...");
▼./html/hello.html
<html> <h1>Hello!</h1> </html>
▼settings.js
exports.port = 3000; exports.host = '182.50.xx.xxx';
npmをインストールしておきましょう。
Node.js をインストールすると付いてくる npm(node package manager) というコマンドを使ってNode.jsのパッケージをインストールすることができます。
インストールには、ローカルインストールとグローバルインストールというものがあります。
ローカルインストールは、カレントディレクトリにパッケージをインストールします。
グローバルインストールは、npmのインストール場所にパッケージをインストールします。
ローカルインストール
# npm install <パッケージ名>
グローバルインストール
# npm install <パッケージ名> -g
テンプレートエンジンのejsを使ってページを表示してみよう
まずは、 ejsをインストールしましょう。
# npm install ejs
▼sample.js
var http = require('http'), fs = require('fs'), ejs = require('ejs'); var settings = require('./settings'); var server = http.createServer(); var template = fs.readFileSync(__dirname + '/html/hello.ejs', 'utf-8'); var n = 0; server.on('request', function(req, res) { n++; var data = ejs.render(template, { title: "hello", content: "<strong>World!</strong>", n: n }); res.writeHead(200, {'Content-Type': 'text/html'}); res.write(data); res.end(); }); server.listen(settings.port, settings.host); console.log("server listening ...");
▼./html/hello.ejs
<html> <h1><%= title %></h1> <p><%- content %></p> <p><%= n %> views</p> </html>
▼解説
このスクリプトでは、アクセスするたびに変数をカウントアップしています。
ejs を読み込まないといけないので、ejs = require(‘ejs’);とします。
fs.readFileSync という命令を使いテンプレートファイルを読み込みます。
第 1 引数はファイル名、第 2 引数は文字コードを指定します。
var data = ejs.render(); と書きテンプレートの中にデータを入れて取得しています。
node.jsで一行掲示板を作ってみよう
querystringというモジュールが必要になるのでインストールしておきます。
node-querystringモジュールは、クエリ文字列のパースおよびオブジェクトからクエリ文字列の組立を行うことができるモジュールです。
#npm install querystring
▼bbs.js
var http = require('http'), fs = require('fs'), ejs = require('ejs'), qs = require('querystring'); var settings = require('./settings'); var server = http.createServer(); var template = fs.readFileSync(__dirname + '/html/bbs.ejs', 'utf-8'); var posts = []; function renderForm(posts, res) { var data = ejs.render(template, { posts: posts }); res.writeHead(200, {'Content-Type': 'text/html'}); res.write(data); res.end(); } server.on('request', function(req, res) { if (req.method === 'POST') { req.data = ""; req.on("readable", function() { req.data += req.read(); }); req.on("end", function() { var query = qs.parse(req.data); posts.push(query.name); renderForm(posts, res); }); } else { renderForm(posts, res); } }); server.listen(settings.port, settings.host); console.log("server listening ...");
▼./html/bbs.ejs
<!doctype html> <html lang="ja"> <head> <title>BBS</title> <meta charset="utf-8"> </head> <body> <form method="post"> <input type="text" name="name"> <input type="submit" value="Post!"> <ul> <% for (var i = 0; i < posts.length; i++ ) { %> <li><%= posts[i] %></li> <% } %> </ul> </body> </html>
▼解説
ejs の中で制御構造を書きたい時は「<% %>」で囲います。
querystring というモジュールが必要になるので、読み込んでいます。qs = require('querystring');
フォームに渡すのは posts と res オブジェクトになるので、「renderForm(posts,res);」と書いています。
フォームからどんどんデータが送られてきて、それを受信している間は "readable" というイベントで取ることができます。
全ての受信が終わったら、というのは “end” というイベントで取得できます。
node.jsからMySqlに接続してみよう
mysqlに接続するのに、nodeのmysqlパッケージが必要になりますのでインストールしましょう。
# npm install mysql
▼mysql_connect.js
var mysql = require('mysql'); var connection = mysql.createConnection({ host: 'localhost', database: 'test', user: 'root', password: 'password' }); var query = connection.query('select * from user;', function (err, results) { console.log('--- results ---'); console.log(results); }); connection.end(function() { console.log('connection end'); });
▼解説
パッケージのmysqlをロードする必要があります。var mysql = require('mysql');
mysql.createConnectionでMysqlに接続し、connection.queryでクエリの発行ができます。
connection.end()でMysqlの接続を解除しています。
------------------------------
作成日:2016年03月21日
更新日:2018年02月12日
------------------------------