Node.jsとは?
Node.jsとは、サーバアプリケーションをJavaScript言語で開発するためのプラットフォームです。
Node.jsを導入することにより、高速でスケーラブルなネットワークアプリケーションを簡単に構築することが可能になります。
例えば、イベント処理が重要で、処理が短く頻繁なチャットアプリなどでNode.jsのメリットが活かしやすいと思います。
ノンブロッキングI/O処理方式
Node.jsはノンブロッキングI/O方式を採用しているため、軽量で、分散されたデバイスにまたがるリアルタイムアプリケーションに適しています。
ノンブロッキングI/Oとは、入出力処理を非同期で実行する方式です。たとえば、データベースにクエリを発行した際、結果が返ってくるまで待ち時間がありますが、ノンブロッキングI/O方式は問い合わせ結果を待たず次の処理に移ります。結果はイベントで受け取ります。
モジュールとパッケージについて
Node.jsでは、JavaScriptで記述されたファイルをモジュールと呼び、それらのモジュール郡をディレクトリにまとめたものをパッケージと呼びます。オフィシャルなパッケージ以外にも、サードパーティ製のモジュールも多数用意されています。代表的なパッケージ公開サイトとしてNode Packaged Modulesがあります。
- Node Packaged Modules
公式サイトで紹介されているサードパーティー製モジュールは下記の通りです。
- パッケージ管理: npm
- HTTP ミドルウェア: Connect
- フレームワーク: Express
- ソケット: Socket.IO
- HTML パーサー: HTML5
- mDNS/Zeroconf/Bonjour
- RabbitMQ, AMQP
- mysql
- シリアライゼーション: msgpack
- Scraping: Apricot
- デバッガ: ndb is a CLI debuggerinspector is a web based tool.
- pcap binding
- ncurses
- Testing/TDD/BDD: vows,
- expresso,
- mjsunit.runner
npm(node package manager)
Node.jsのパッケージを管理するためのツールとして、npm(node package manager)というツールが用意されています。
このツールを使って、簡単にパッケージを導入したり、更新・削除といった処理を行うことができます。
パッケージをインストール
パッケージのインストールはinstallオプションにパッケージ名を指定します。
npm install [-g] パッケージ名
カレントディレクトリに node_modules というフォルダが作成され、その中に指定したパッケージがインストールされます。
インストールしたパッケージを使うには、requireを使ってパッケージを読み込みます。
var pkg = require("パッケージ名");
- -gオプション
-g オプションで、すべてのプロジェクトから利用可能な領域にインストールされます。
どのプロジェクトでも共通して利用するようなパッケージで使うと良いでしょう。
パッケージのアンインストール
uninstall オプションで、指定したパッケージがアンインストールされます。
npm unisntall [-g] パッケージ名
インストール済のパッケージのリストを表示
listオプションで、インストール済パッケージの一覧が表示されます。
npm list [-g]
パッケージ情報を表示
infoオプションで、指定したパッケージの情報が表示されます。
npm info パッケージ名
人気のパッケージ
Socket.IO
WebSocketです。チャットなどのリアルタイム通信に有用です。
npm install socket.io
Express
MVCの自動生成、ルーティング機能などを持ったフレームワークです。
npm install express
EJS
Expressから利用できるテンプレートエンジンです。
npm install ejs
node-mysql
MySQLへ接続するためのパッケージです。
npm install mysql
jsdom
DOM操作が使えるようになるパッケージです。
npm install jsdom
node-validator
バリデーションや文字列操作、サニタイジングを行うパッケージです。
npm install validator
モジュールの読み込み
Node.jsにはモジュールを読み込むための関数 require() が用意されています。
require()は引数指定されたモジュールを読み込み、そのモジュールに含まれるメソッドやクラスを格納したオブジェクトを返します。このオブジェクトを通じてモジュール内のコンテンツにアクセスできるようになります。
httpモジュールを利用するには、次のようにrequireの引数に指定し、モジュールと同名のローカル変数に代入します。
var http = require('http');
読み込んだモジュール内の関数は.演算子で呼び出せます。
var server = http.createServer();
シンプルなモジュールの作成
シンプルなモジュールを作成し、呼び出すサンプルです。
モジュールmod.jsと、それを呼び出すmain.jsを作成し、それぞれに下記の内容を記述します。
exports.printBoo = function(){
return "Hello!";
}
上記ではexportsにprintBoo()メソッドを追加し、エクスポートしています。
こうすることで別ファイルから該当メソッドを呼び出すことができます。
var mod = require('./mod.js');
console.log( mod.printBoo() );
mod.jsモジュールを読み込み、先ほどエクスポートしたprintBoo()メソッドを実行し、それをコンソールに出力しています。
下記を実行すると、コンソールに Hello!と出力されます。
node main.js
コアモジュール
node.jsに標準で組み込まれているモジュールはコアモジュールと呼ばれます。
require('モジュール名')
コアモジュール一覧
モジュール名 | 機能 | 安定度 |
---|---|---|
assert | アサーション | 5 |
buffer | バイト列の格納・操作 | 3 |
child_process | 子プロセスの生成・管理 | 3 |
cluster | 複数のプロセスを使った負荷分散 | 1 |
console | コンソールへのメッセージ出力 | 4 |
crypto | 暗号化/ハッシュ | 2 |
dgram | UDPを扱うソケット関連の処理 | 3 |
dns | DNS関連の処理 | 3 |
domain | 複数のIO処理間の連携 | 1 |
events | イベント処理を実装するための基底クラス | 4 |
fs | ファイルおよびファイルシステムの操作 | 3 |
http | HTTPサーバー/クライアント | 3 |
https | HTTPSサーバー/クライアント | 3 |
net | ソケットの操作 | 3 |
os | OS情報の取得 | 4 |
path | パス文字列の処理 | 3 |
punycode | Punycode文字列のエンコード/デコード | 2 |
querystring | クエリ文字列の処理 | 3 |
readline | 標準入出力を使用した対話的インターフェイス | 2 |
repl | REPL | (なし) |
stream | ストリーム入出力処理の基底クラス | 2 |
string_decoder | バイナリ列から文字列へのデコード | 3 |
tls | OpenSSLを使ったTLS/SSL通信 | 3 |
tty | TTYの情報取得 | 2 |
url | URL文字列のパース・フォーマット | 3 |
util | 各種ユーティリティ | 5 |
vm | JavaScriptの実行エンジン | 2 |
zlib | zlibを使ったデータの圧縮・展開 | 3 |
実装
最初に
適当なフォルダーを作成し、ターミナルでそこへ移動します。
まず以下のコマンドを実行してください。
npm init --yes
これは、npmの設定ファイルであるpackage.json
を生成するコマンドです。package.json
には、npmパッケージの設定情報などが書き込まれていきます。
最もシンプルなHTTPサーバを作成
ブラウザでアクセスすると「Hello World」というメッセージを表示するHTTPサーバを作成します。
まず、先に作成したフォルダ以下にコードをapp.jsとして保存します。
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(8300, "127.0.0.1");
console.log('Server running at http://127.0.0.1:8300');
httpモジュールをhttpオブジェクトとしてロードしています。
次にhttpモジュールのcreateServerメソッドにはHTTPリクエストを処理してレスポンスを返すHTTPサーバアプリケーションとしての処理を定義する関数を指定します。
このサンプルでは無名関数としてリクエストの内容にかかわらず,レスポンスとして,ヘッダをステータスコード200 OKでContent-Typeにtext/plainを返し,レスポンスボディとして「Hello World」を書き出しています。
createServerメソッドはHTTPサーバオブジェクトを返し,さらにそのlistenメソッドで8300番ポートとループバックアドレスにバインドしてサーバを開始します。
nodeコマンドの引数に作成したファイル名を指定して実行します。
node app.js
ブラウザを開いて「localhost:8300」or「127.0.0.1:8300」というURLにアクセスします。
参考
このように Hello World と表示されれば成功です。
jsファイルを変更した際にはサーバーを再起動しないと反映されないので注意。
一度サーバーを停止してから再度サーバーを起動することで再起動ができます。
ファイルの変更を反映したい場合は、Ctrl + C
でサーバーを停止した後に、 node app.js
でサーバーを再起動しましょう。
おそらく普段使われている言語では,WebサーバとしてTomcatやApache+CGIといったアプリケーションを動作させるコンテナがある状態で,中身のアプリケーションだけを,サーブレットのように定まった仕様で構築することが多いでしょう。nodeの場合は,前述のサンプルのようにそれ自身でコンテナとなるWebサーバもアプリケーションも,どちらもまとめて実装することになります。
ファイル更新時に自動でサーバーが再起動するようにしよう
ページを表示することはできましたが、jsファイルの変更を反映するには、毎回サーバーを再起動する必要があります。
手動でサーバーを再起動する必要がないように、ファイルが変更されると自動でサーバーを再起動してくれるnodemonというnpmパッケージをインストールしていきましょう。
npm install nodemon
次に、nodemonを使ってサーバーを起動していきましょう。nodemonを実行するには、以下のコマンドを実行してください。(コピーしたコマンドはCtrl + Vもしくは Ctrl + Shift + V で貼り付けることができます。)
- Windowsの場合
- Macの場合
以下の図の下部のように表示されれば、nodemonでのサーバー起動は成功です。
nodemonを簡単に呼び出そう
サーバーを起動するために .\\node_modules\\.bin\\nodemon app.js
と入力するのは少し面倒です。
これをより簡単に実行できるようにしていきましょう。
ここでいう「nodejs_test」に値するフォルダの中にあるpackage.json
を開いてください。
すると、package.json
の中にscripts
という項目があるのが確認できるかと思います。
このscripts
の中に、よくつかうコマンドをタスクとして登録することで、登録したタスクを簡単に呼び出すことができます。
それでは、実際にタスクを登録していきましょう。
ここでは、scripts
にもともと書いてあるtest
というタスクを削除しstart
というタスクを登録していきます。 "test": 〜
の行を削除し、以下のコマンドを貼り付けてください。
- Windowsの場合
- Macの場合
登録したstart
というタスクを実行しましょう。
npm run タスク名
という形で実行できます。
以下のように実行し、nodemonでサーバーが起動できるかを確認してください。
npm run start
これで、簡単にサーバーを起動できるようになりました!
Expressの概要
expressは、nodeを使ったWebアプリケーションを作成するためのフレームワークです。
非常にシンプルで軽量なフレームワークで、HTMLやCSSのテンプレートエンジンや、Cookie処理を行うcookieモジュール、HTTPリクエストを処理するConnectモジュールといった多彩なモジュールを必要に合わせて組み合わせることができます。
簡単なExpressの利用方法
Expressを使って簡単なHTTPサーバを構築します。
HTMLとCSSのテンプレートエンジンは複数用意されているので、任意のエンジンをインストールして選択することができます。
デフォルトのテンプレートエンジンはJadeですが、ここではPHPと同じように使えるejs(Embedded JavaScript)を使います。--cssオプションでlessやstylusといったCSSエンジンも指定可能です。
expressとejsをインストールします。以下のコマンドを実行してください。
npm install express ejs
※npm install express
npm install ejs
と1つずつinstallコマンドを実行していくことも可能ですが、 npm intall インストールしたいパッケージ① インストールしたいパッケージ②...
というようにパッケージ名を列挙することで、一度にまとめてインストールすることができます。よく使う便利な方法なので覚えておきましょう。
プロジェクトの作成
express コマンドを使うことで、プロジェクトを生成できます。
express コマンドを使うために、以下を実行します。
npm install -g express-generator
ここではテンプレートエンジンにejsを指定し、exp01というプロジェクト名を指定しています。
実行後、プロジェクト名のexp01でディレクトリが作成され、その中に必要なファイル・ディレクトリ一式が展開されます。
express --view=ejs exp01
作成されたディレクトリに移動し、依存関係にあるパッケージ・モジュールをインストールします。
cd exp01
npm install
npmのオプション一覧は下記で確認できます。
npm help
上図の「run the app」に記載されているコマンドを実行すると、Expressのデフォルトのポート番号3000で作成したWebサーバが起動します。
SET DEBUG=exp01:* & npm start
もしくは、
npm start
npm run start
でも起動します。
ブラウザからは
「http://localhost:3000」
といったアドレスでアクセスできるようになります。
Expressプロジェクトについて注意
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
最もシンプルなHTTPサーバを作成のapp.jsでは、サーバを立てる処理(listenメソッド)を記述していましたが、上記ソースでは記述していません。そのため、
node app.js
としてもサーバは起動しません。
サーバを立てる処理は「C:\Users...\nodejs_test\exp01\bin\www」に記述されています。
サーバを立てる際は、「www」ファイルを実行するタスクとして、「package.json」内の「scripts」項目にて「start」が定義されているのでそれを利用します。
{
"name": "exp01",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"cookie-parser": "~1.4.4",
"debug": "~2.6.9",
"ejs": "~2.6.1",
"express": "~4.16.1",
"http-errors": "~1.6.3",
"morgan": "~1.9.1"
}
}
- 「C:\Users...\nodejs_test\exp01\bin\www」
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('exp01:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
参考