Node.js入門 – とほほのWWW入門





Node.js入門 – とほほのWWW入門


Node.js入門


トップ >
Node.jsメモ

目次



Node.js とは

  • サーバーサイドの JavaScript 実行環境。
  • Google V8 JavaScript エンジンを使用しており、高速。
  • Linux サーバにインストールして使用することが多いが、macOS 版や、Windows 版もある。
  • npm (Node Package Manager) と呼ばれるパッケージ管理システムを同梱。
  • ノンブロッキングI/O と イベントループ アーキテクチャにより、10K問題 (クライアント1万台レベルになると性能が極端に悪化する問題) に対応。
  • 通信やファイルの読み書きをノンブロッキングI/Oで処理するため、スレッドが I/O 待ちになる頻度が少なく、効率的。
  • クライアントからパケットを読み込む、ファイルの次のブロックを読み出すなどすべてがイベント処理で実装されている。
  • 基本的にはシングルスレッドだが、内部では暗号化などの重い処理を複数スレッドで処理。
  • 基本的にはシングルプロセスだが、JavaScript から fork() を呼び出すことで、マルチプロセスも可能。
  • ライセンスは MITライセンス。商用利用可能。
  • 長期サポートの LTS(Long Term Support)版と、非LTS版がある。
  • 今のところ、v6, v8 等の偶数系は LTS 版。v7, v9 等の奇数系は非 LTS 版。
  • 現在の最新版は v9 系だが、2018年中頃にはサポート終了。v8 系は、LTS 版のため、2019年12月までサポート継続。
  • Node.js 上のフレームワークとして、Express, Meteor, Sails, Koa, LoobBack などがある。
  • MEAN(MongoDB+Express+AngularJS+Node.js)と呼ばれる構成で利用されることも多い。
  • HTTP 通信のみでなく、TCP や UDP 通信も可能。
  • WebSocker サーバとして利用されることも多い。
  • 比較的小規模で、高パフォーマンスを要求されるプロジェクトでの利用が多い。
  • AWS Lambda, PayPal, Walmart, Uber など大量アクセス領域で利用されている。
  • 非互換強化を含むバージョンアップがあり、仕様の安定期に入るには、もう少しだけかかりそう。

本書では現時点で最新の LTS 版である v8.9.4 をベースに説明します。


歴史

  • 2009年 ?月、カリフォルニア州のライアン・ダール(Ryan Dahl)氏、Node.js の開発に着手。
  • 2011年 8月、Dahl 氏、Node.js 初期公開バージョン 0.1.14 をリリース。
  • 2012年 ?月、Joyent 社、Node.js 開発支援を開始。Dahl 氏も Joyent 社の社員に。
  • 2012年 1月、BDFL(優しい終身の独裁者)の時代を終え、開発リーダが Dahl 氏から Isaac Z. Schlueter 氏に変更。
  • 2014年 ?月、開発リーダが、Schlueter 氏から TJ Fontaine 氏に変更。
  • 2014年 ?月、Node.js Core の開発が停滞しはじめ、一部の推進者が新団体 Node Forward を設立。
  • 2015年 1月、Node Forward、 Node.js の fork 版である io.js 1.0 をリリース。
  • 2015年 2月、Joyent 社、Node.js Foundation 設立をアナウンス。
  • 2015年 5月、Node Forward、io.js 2.0 をリリース。
  • 2015年 5月、io.js も Node.js Foundation への統合を選択。
  • 2015年 7月、Joyent 社、Node.js Foundation を設立。
  • 2015年 8月、Node Forward、io.js 3.0 をリリース。
  • 2015年 9月、Node.js と io.js の最初の統合版 Node.js 4.0 をリリース。
  • 2015年10月、Node.js 5.0 をリリース。
  • 2016年 4月、Node.js 6.0 をリリース。
  • 2016年 7月、韓国 Samsung 社が、Joyent 社を買収。
  • 2016年10月、Node.js 7.0 をリリース。
  • 2017年 5月、Node.js 8.0 をリリース。
  • 2017年10月、Node.js 9.0 をリリース。


JavaScript関連技術

JavaScript/Node.js 関連技術を下記で紹介しています。


インストール

Node.js はバージョンの変動が激しく、バージョンを上げたり戻したりすることがよくあります。CentOS/RHEL 標準の yum や、Ubuntu/Debian 標準の apt-get でインストールするよりも、nvm, nodebrew, n などの、Node.js 用パッケージ管理を用いてインストールする方がおすすめです。


yum の場合 (CentOS)

CentOS のシステム領域に、特権モードでインストールします。インストールされるバージョンは少し古いものになります。

Console


# yum -y install epel-release     EPEL リポジトリ情報をインストールする
# yum -y install nodejs           Node.js をインストールする
# yum -y install npm              npm をインストールする


apt-get の場合 (Ubuntu)

Ubuntu のシステム領域に、特権モードでインストールします。インストールされるバージョンは少し古いものになります。標準だと nodejs コマンドとしてインストールされるため、update-alternatives を用いて nodejs を node に変更します。

Console


$ sudo apt-get update               必要に応じてパッケージをアップデートする
$ sudo apt-get install nodejs       Node.js をインストールする
$ sudo apt-get install npm          npm をインストールする
$ sudo update-alternatives --install /usr/bin/node node /usr/bin/nodejs 10


nvm の場合 (CentOS/Ubuntu)

個人のホームディレクトリ配下に複数のバージョンをインストールします。環境変数で使用するバージョンを切り替えます。

Console


$ git clone https://github.com/creationix/nvm.git ~/.nvm
$ source ~/.nvm/nvm.sh
$ nvm ls-remote             インストール可能なバージョンの一覧を表示する
$ nvm install v8.9.4        最新の LTS 版をインストール
$ nvm install v9.3.0        最新版をインストール
$ nvm ls                    インストールされているバージョンの一覧を表示する
$ nvm use v8.9.4            一時的に v8.9.4 を使用する(再ログイン時にはデフォルトに戻る)
$ nvm alias default v8.9.4  デフォルトを v8.9.4 に切り替える

再ログイン時にも nvm を有効にするために、~/.bash_profile に下記を追記しておきます。

~/.bash_profile


if [ -s ~/.nvm/nvm.sh ]; then
  source ~/.nvm/nvm.sh
fi


nodebrew の場合 (CentOS/Ubuntu)

個人のホームディレクトリ配下に複数のバージョンをインストールします。シンボリックリンクで使用するバージョンを切り替えます。

Console


$ curl -L git.io/nodebrew | perl - setup
$ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bashrc
$ source ~/.bashrc
$ nodebrew ls-remote                インストール可能なバージョンの一覧を表示する
$ nodebrew install-binary v8.9.4    最新の LTS 版をインストール
$ nodebrew install-binary v9.3.0    最新版をインストール
$ nodebrew ls                       インストールされているバージョンの一覧を表示する
$ nodebrew use v8.9.4               v8.9.4 を使用する


n の場合 (Ubuntu)

Ubuntu の場合、n を推奨するサイトが多いようです。まず、n をインストールするために apt-get で nodejs と npm をインストールし、npm で n をインストールした後、apt-get でインストールした nodejs と npm は削除します。

Console


$ sudo apt-get update               必要に応じてアップデートする
$ sudo apt-get install -y nodejs    nodejs をインストールする
$ sudo apt-get install -y npm       npm をインストールする
$ sudo npm cache clean              npm のキャッシュをクリアする
$ sudo npm install -g n             npm で n をインストールする
$ sudo n 8.9.4                      n で Node.js v8.9.4 をインストールする
$ sudo n 9.3.0                      n で Node.js v9.3.0 に切り替える
$ sudo n 8.9.4                      v8.9.4 に戻す
$ sudo apt-get purge -y nodejs npm  apt-get でインストールした nodejs と npm をアンインストールする


PPA の場合 (Ubuntu)

PPA(Personal Package Archive) は、NodeSource が管理するモジュールをインストールします。

Console


$ sudo apt-get update               必要に応じてパッケージをアップデートする
$ sudo add-apt-repository ppa:chris-lea/node.js   PPA をインストールする
$ curl -sL https://deb.nodesource.com/setup_9.x | sudo -E bash -  9.x リポジトリ情報をインストール
$ sudo apt-get install -y nodejs    Node.js をインストールする


Hello world (コンソール版)

まずは、おきまりの Hello world から。$ は一般ユーザの、# は特権ユーザのプロンプトを示します。

sample1.js


console.log("Hello world!");

Console


$ node sample1.js
Hello world!


Hello World (Web版)

Web サーバとして動作させる場合のサンプルがこちら。

sample2.js


var http = require('http');
var server = http.createServer(function(req, res) {
  res.write("Hello world!n");
  res.end();
}).listen(8080);

まず、サーバを起動する。

Console


$ node sample2.js

別の端末から、Node.js を呼び出す。

Console


$ curl http://127.0.0.1:8080/
Hello world!


コンソールに改行無しで書き出す

Node.js


process.stdout.write("Hello");


クライアントからの情報を得る

Node.js


var http = require('http');
var server = http.createServer(function(req, res) {
  console.log("URL: " + req.url);
  console.log("Method: " + req.method);
  console.log("Header[Content-Type]: " + req.headers['content-type']);
  res.end();
}).listen(8080);


アプリケーションフォルダを作成する

Console


$ mkdir ~/myapp
$ cd ~/myapp
$ npm init
(略)
name: (myapp) [Enter]
version: (1.0.0) [Enter]
description: [Enter]
entry point: (index.js) [Enter]
test command: [Enter]
git repository: [Enter]
keywords: [Enter]
author: [Enter]
license: (ISC) [Enter]
(略)
Is this ok? (yes) yes
$ ls -l
total 4
-rw-rw-r--. 1 taro taro 201  Jan  3 22:54 package.json


アプリケーションフォルダにパッケージをインストールする

例として jquery パッケージをインストールします。

Console


$ cd ~/myapp
$ npm install jquery
$ ls -l
total 4
drwxrwxr-x. 3 taro taro  19  Jan  3 22:56 node_modules
-rw-rw-r--. 1 taro taro 290  Jan  3 22:54 package-lock.json
-rw-rw-r--. 1 taro taro 201  Jan  3 22:54 package.json
$ ls -l ./node_modules
total 4
drwxrwxr-x. 5 taro taro 4096 Jan  3 22:56 jquery
$

–save オプションを用いると、インストールしたパッケージ情報を package.json ファイルに書き込みます。

Console


$ npm install jquery --save


GET パラメータを受け取る

GET のパラメータは req.url で受け取れますが、url モジュールを用いてこれをパースすることができます。

Node.js


var http = require('http');
var url = require('url');

var server = http.createServer(function(req, res) {
  var url_parse = url.parse(req.url, true);
  console.log(url_parse);
  res.end();
}).listen(8080);

クライアント側


$ curl -X GET http://localhost:8080/test?name=Taro

サーバ側


$ node app.js
Url {
  protocol: null,
  slashes: null,
  auth: null,
  host: null,
  port: null,
  hostname: null,
  hash: null,
  search: '?name=Taro',
  query: { name: 'Taro' },
  pathname: '/test',
  path: '/test?name=Taro',
  href: '/test?name=Taro' }


POST データを受け取る

on() はイベントハンドラを登録します。下記の例では、オブジェクト req に対して data 受信のイベント発生時に断片データ(chunk)を受け取り、body 変数に連結しておき、受信完了の end イベント発生時に、その内容をコンソールに書き出します。

Node.js


var http = require('http');

var server = http.createServer(function(req, res) {
  if (req.method == 'POST') {
    var body = '';
    req.on('data', function(chunk) {
        body += chunk;
    });
    req.on('end', function() {
      console.log(body);
      res.end();
    });
  }
}).listen(8080);

クライアント側


$ curl -X POST -d 'name=Taro' http://localhost:8080/test

サーバ


$ node app.js
name=Taro


Express で GET POST を処理する

まず、express モジュールをインストールします。

Console


$ cd ~/myapp            作成済のアプリケーションフォルダに移動
$ npm install express   Express パッケージをインストール

サーバプログラムを用意します。

Node.js


var express = require('express');
var app = express();
app.listen(8080);

app.get('/test1', function(req, res) {
  res.send('TEST1n');
});

app.post('/test2', function(req, res) {
  res.send('TEST2n');
});

クライアントから呼び出します。

Node.js


$ curl -X GET http://localhost:8080/test1
TEST1
$ curl -X POST http://localhost:8080/test2
TEST2


Express で POST データを受け取る

Express で POST データを受け取る方法は、バージョンによってかなり変動しています。Node.js 4.0 以降では body-parser モジュールを使用します。

Node.js


// 古い書き方(1): bodyDecorder時代
app.use(express.bodyDecoder());

// 古い書き方(2): bodyParser時代
app.use(express.bodyParser());

// 古い書き方(3): urlencoded時代
app.use(express.urlencoded());
app.use(express.json());

// 現時点の新しい書き方: body-parser時代
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false });


RAW データを受け取る

raw() を用いて POST データをバイナリデータとして受け取ります。

Node.js


var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.raw({ type:'*/*' }));

app.post('/', function(req, res) {
  console.log(req.body);
  res.end();
});
app.listen(8080);

クライアント側


$ curl -X POST -d 'Hello' http://localhost:8080/


TEXT データを受け取る

text() を用いて POST データをテキストデータとして受け取ります。

Node.js


var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.text({ type:'*/*' }));

app.post('/', function(req, res) {
  console.log(req.body);
  res.end();
});
app.listen(8080);

クライアント側


$ curl -X POST -d 'Hello' http://localhost:8080/


FORM データを受け取る

urlencoded() を用いて POST された FORM データを受け取ります。デコーダとして、extended:true の場合は qs ライブラリを、extended:false の場合は querystring ライブラリを使用します。デフォルトは true です。qs ライブラリの場合は、name[1]=Taro, name[2]=Jiro などの配列も解釈してくれます。

Node.js


var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended:true}));

app.post('/', function(req, res) {
  for (key in req.body) {
    console.log(key, '=', req.body[key]);
  }
  res.end();
});
app.listen(8080);

クライアント側


$ curl -X POST -d 'name[1]=Yamada&name[2]=Taro&age=36' http://localhost:8080/


JSON データを受け取る

json() を用いて JSON データを受け取ります。

Node.js


var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());

app.post('/', function(req, res) {
  for (key in req.body) {
    console.log(key, '=', req.body[key]);
  }
  res.end();
});
app.listen(8080);

クライアント側


$ curl -X POST 
  -H 'Content-Type: application/json' 
  -d '{"name":["Yamada","Taro"],"Age":36}' 
  http://localhost:8080/


EJS テンプレートエンジンを用いる

EJS(Effective JavaScript templating) を用いて、HTML テンプレートなどに変数を埋め込むことが可能となります。まず、ejs をインストールします。

Console


$ cd ~/myapp
$ npm install ejs --save

views フォルダを作成し、その下に test.ejs ファイルを作成します。

views/test.ejs


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><%=title %></title>
</head>
<body>
<h1><%=title %></h1>
<p><%-content %></p>
</body>
</html>

シンプルにレンダリングするには下記の様に用います。

app.js


var fs = require('fs');
var ejs = require('ejs');
var template = fs.readFileSync('./views/test.ejs', 'utf8');

var buf = ejs.render(template, {
  title: "EJS Sample Code",
  content: "This is EJS Sample..."
});
console.log(buf);

app.engine() を用いて標準レンダリングエンジンに指定することもできます。

app.js


var express = require('express');
var app = express();
var ejs = require('ejs');
app.engine('ejs', ejs.renderFile);
app.get('/', function(req, res) {
  res.render('test.ejs', {
    title: "EJS Sample Code",
    content: "This is EJS Sample..."
  });
});
app.listen(8080);

テンプレートでは下記の記法を使用できます。<%= の場合は < などの文字が &lt; に置換されます。%lt;%- の場合は置換されません。<% スクリプトはレンダリング時にサーバー側で実行されます。

テンプレート


<%=変数名(HTMLエンコードあり) %>
<%-変数名(HTMLエンコードなし) %>
<% スクリプト %>
<%# コメント %>
<%%   '<%' を文字列として表示したい場合に使用
 %>   通常の閉じタグ
-%>   後続する改行や空白文字を削除(トリム)する


ファイルをノンブロッキングで読み出す

Node.js


var fs = require("js");

fs.readFile("./data.dat", "utf8", function(err, data) {
  console.log(data);
});


モジュールを作成する

exports を用いて、モジュールを作成することができます。

mymod.js


exports.hello = function() {
  return "Hello!";
}

app.js


var mymod = require('./mymod');
console.log(mymod.hello());

モジュール名が / で始まる場合は絶対パス、./ で始まる場合は相対パス、その他の場合は (2)コアモジュール(module.exports._buildinLibs)、(2)module.paths 配列、(3)環境変数 NODE_PATH の順番で探索します。拡張子(.js) は省略可能です。フォルダ名を指定した場合はその配下の index.js を読み込みます。index.js のファイル名は package.json の “main” パラメータで変更可能です。


文字列中の変数を展開する

ES6(ES2015) で導入された Template Literal にも対応しており、バッククォート(`) 文字列の中で、${変数名} を展開することが可能です。

Node.js


const PORT = 8080;
console.log(`localhost:${PORT}`);





Copyright (C) 2016-2018 杜甫々

初版:2016年6月4日 最終更新:2018年1月7日

http://www.tohoho-web.com/ex/nodejs.html





Related Articles

Leave a Reply

Back to top button