本書では現時点で最新の LTS 版である v8.9.4 をベースに説明します。
JavaScript/Node.js 関連技術を下記で紹介しています。
Node.js はバージョンの変動が激しく、バージョンを上げたり戻したりすることがよくあります。CentOS/RHEL 標準の yum や、Ubuntu/Debian 標準の apt-get でインストールするよりも、nvm, nodebrew, n などの、Node.js 用パッケージ管理を用いてインストールする方がおすすめです。
CentOS のシステム領域に、特権モードでインストールします。インストールされるバージョンは少し古いものになります。
# 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
Ubuntu のシステム領域に、特権モードでインストールします。インストールされるバージョンは少し古いものになります。
# 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
個人のホームディレクトリ配下に複数のバージョンをインストールします。環境変数で使用するバージョンを切り替えます。Ubuntu 22.04 コンテナでは curl コマンドをインストールしないとnvm ls-remote で一覧を取得できませんでした。CentOS 7 コンテナで試すと OS のライブラリが古すぎて v18.16 は動きませんでした。
# 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 に下記を追記しておきます。
if [[ -s ~/.nvm/nvm.sh ]]; then source ~/.nvm/nvm.sh fi
個人のホームディレクトリ配下に複数のバージョンをインストールします。シンボリックリンクで使用するバージョンを切り替えます。
$ 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 を使用する
Ubuntu の場合 n を推奨するサイトが多いようです。まず、apt で nodejs と npm をインストールし、npm で n をインストールし、n で node と npm の指定バージョンをインストールし、apt でインストールした古い nodejs と npm を削除します。
$ 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
PPA(Personal Package Archive) は、NodeSource が管理するモジュールをインストールします。
$ 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 から。$ は一般ユーザの、# は特権ユーザのプロンプトを示します。
console.log("Hello world!");
$ node sample1.js Hello world!
Web サーバとして動作させる場合のサンプルがこちら。
var http = require('http'); var server = http.createServer(function(req, res) { res.write("Hello world!\n"); res.end(); }).listen(8080);
まず、サーバを起動する。
$ node sample2.js
別の端末から、Node.js を呼び出す。
$ curl http://127.0.0.1:8080/ Hello world!
process.stdout.write("Hello");
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);
$ 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 オプションは不要です。
$ cd ~/myapp $ npm install express
GET のパラメータは req.url で受け取ります。url モジュールでパースすることもできます。
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 の場合、データは分割して受け取ることがあります。下記の例では、オブジェクト req に対して data 受信のイベント発生時に断片データ(chunk)を受け取り、body 変数に連結しておき、受信完了の end イベント発生時に、その内容をコンソールに書き出します。
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 モジュールをインストールします。
$ cd ~/myapp 作成済のアプリケーションフォルダに移動 $ npm install express Express パッケージをインストール
サーバプログラムを用意します。
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'); });
クライアントから呼び出します。
$ curl -X GET http://localhost:8080/test1 TEST1 $ curl -X POST http://localhost:8080/test2 TEST2
Express 4.xで POST データを受け取る方法は下記の様にします。
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);
$ 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() を用いて POST データをバイナリデータとして受け取ります。
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);
$ curl -X POST -d 'Hello' http://localhost:8080/
text() を用いて POST データをテキストデータとして受け取ります。
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/
urlencoded() を用いて POST された FORM データを受け取ります。デコーダとして、extended:true の場合は qs ライブラリを、extended:false の場合は querystring ライブラリを使用します。デフォルトは true です。qs ライブラリの場合は、name[1]=Taro, name[2]=Jiro などの配列も解釈してくれます。
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 データを受け取ります。
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(Effective JavaScript templating) を用いて、HTML テンプレートなどに変数を埋め込むことが可能となります。まず、ejs をインストールします。
$ npm install 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>
シンプルにレンダリングするには下記の様に用います。
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() を用いて標準レンダリングエンジンに指定することもできます。
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);
テンプレートでは下記の記法を使用できます。<%= の場合は < などの文字が < に置換されます。<%- の場合は置換されません。<% スクリプトはレンダリング時にサーバー側でスクリプトを実行します。
<%=変数名(HTMLエンコードあり) %> <%-変数名(HTMLエンコードなし) %> <% スクリプト %> <%# コメント %> <%% '<%' を文字列として表示したい場合に使用 %> 通常の閉じタグ -%> 後続する改行や空白文字を削除(トリム)する
var fs = require("fs"); fs.readFile("./data.dat", "utf8", function(err, data) { console.log(data); });
exports を用いて、モジュールを作成することができます。
exports.hello = function() { return "Hello!"; }
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 にも対応しており、バッククォート(`) 文字列の中で、${変数名} を展開することが可能です。
const PORT = 8080; console.log(`localhost:${PORT}`);