とほほのNode.js入門

トップ > Node.jsメモ

目次

Node.js とは

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

歴史

JavaScript関連技術

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

インストール

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

yum の場合 (CentOS)

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

Console
# CentOS 7
# yum -y install epel-release
# yum -y install nodejs
# node --version
v16.18.1
# yum -y install npm
8.19.2

# Rocky Linux 8
# yum -y install nodejs
# node --version
v10.24.0
# npm --version
6.14.11
apt の場合 (Ubuntu)

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

Console
# Ubuntu 22.04
$ sudo apt update
$ sudo apt -y install nodejs
$ node --version
v12.22.9
$ sudo apt -y install npm
$ npm --version
8.5.1
nvm の場合 (CentOS/Ubuntu)

個人のホームディレクトリ配下に複数のバージョンをインストールします。環境変数で使用するバージョンを切り替えます。Ubuntu 22.04 コンテナでは curl コマンドをインストールしないとnvm ls-remote で一覧を取得できませんでした。CentOS 7 コンテナで試すと OS のライブラリが古すぎて v18.16 は動きませんでした。

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

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

~/.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 v18.16.0  v18.16.0(LTS) 版をインストール
$ nodebrew install-binary v20.3.0   v20.3.0 をインストール
$ nodebrew ls                       インストールされているバージョンの一覧を表示する
$ nodebrew use v18.16.0             v18.16.0 を使用する
n の場合 (Ubuntu)

Ubuntu の場合 n を推奨するサイトが多いようです。まず、apt で nodejs と npm をインストールし、npm で n をインストールし、n で node と npm の指定バージョンをインストールし、apt でインストールした古い nodejs と npm を削除します。

Console
$ sudo apt update                   必要に応じてアップデートする
$ sudo apt install -y curl          curl をインストールする
$ sudo apt install -y nodejs        nodejs をインストールする
$ sudo apt install -y npm           npm をインストールする
$ sudo npm install -g n             npm で n をインストールする
$ sudo apt purge -y nodejs npm      apt でインストールした nodejs と npm をアンインストールする
$ hash -r                           パスキャッシュをクリアする
$ sudo n ls-remote                  利用可能なバージョンの一覧を表示する
$ sudo n 18.16.0                    n で Node.js v18.16.0(LTS) をインストールする
$ sudo n 20.3.0                     n で Node.js v20.3.0 に切り替える
$ sudo n ls                         インストールされているバージョンの一覧を表示する
$ sudo n 18.16.0                    v18.16.0 に戻す
$ node --verison
v18.16.0
$ npm --version
9.5.1
リポジトリを利用する場合 (Ubuntu)

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

Console
$ sudo apt update                   必要に応じてパッケージをアップデートする
$ curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash -  9.x リポジトリ情報をインストール
$ sudo apt-get install -y nodejs    Node.js をインストールする
$ node --version
v18.16.0
$ npm --version
9.5.1

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

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

例として express パッケージをインストールします。npm 5.x 以降では --save オプションは不要です。

Console
$ cd ~/myapp
$ npm install express

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 データを受け取る

POST の場合、データは分割して受け取ることがあります。下記の例では、オブジェクト 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('TEST1\n');
});

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

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

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

Express で POST データを受け取る

Express 4.xで POST データを受け取る方法は下記の様にします。

Node.js
const express = require('express');
const app = express();

app.use(express.urlencoded({ extended: true }));

app.post('/', (req, res) => {
  console.log(req.body);
  res.send('OK\n');
});

app.listen(8080);
Console
$ curl -X POST -d 'name=Yamada&age=26' http://localhost:8080/

express.urlencoded() の部分は express のバージョンによって色々変更があるようです。元々は bodyDecoder() でしたが bodyParser() に名称変更。Express4 では body-parser という別モジュールに切り出されたのですが、再度 express に同梱されました。

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

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

// 古い書き方(3): Express4前期 urlencoded + body-parser時代
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false });

// 新しい書き方: Express4後期 urlencoded 時代
app.use(express.urlencoded({ extended: true }));
RAW データを受け取る

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

Node.js
var express = require('express');
var app = express();

app.use(express.raw({ type:'*/*' }));

app.post('/', function(req, res) {
  console.log(req.body);
  res.send('OK\n');
});
app.listen(8080);
Console
$ curl -X POST -d 'Hello' http://localhost:8080/
TEXT データを受け取る

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

Node.js
var express = require('express');
var app = express();

app.use(express.text({ type:'*/*' }));

app.post('/', function(req, res) {
  console.log(req.body);
  res.send('OK\n');
});
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();

app.use(express.urlencoded({extended:true}));

app.post('/', function(req, res) {
  console.log(req.body);
  res.send('OK\n');
});
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();

app.use(express.json());

app.post('/', function(req, res) {
  console.log(req.body);
  res.send('OK\n');
});
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
$ npm install ejs

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; に置換されます。<%- の場合は置換されません。<% スクリプトはレンダリング時にサーバー側でスクリプトを実行します。

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

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

Node.js
var fs = require("fs");

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-2023 杜甫々
初版:2016年6月4日 最終更新:2023年6月11日
http://www.tohoho-web.com/ex/nodejs.html