「Node.js超入門」の感想・備忘録1

スポンサーリンク

書籍「Node.js超入門」のまとめ。

点数

87点

感想

とてもわかりやすかった。
今後Node.jsを実務でどう使っていくか、は考えていかなければならないと思う。

Node.jsとは

Javascriptのランタイム環境。
V8エンジンというJavaScriptランタイムエンジンを使用している。
(ver.10からはv8エンジンに依存しなくなったらしい)
最近は、JavaScriptのライブラリがNode.jsのライブラリ管理ツールを利用しているため、JavaScriptの開発プラットフォームの役割を果たすようになっている。

webサーバー機能のためのライブラリがある。
Expressという有名なフレームワークがある。

2つのバージョン

  • 偶数バージョン=LTS
  • 奇数バージョン=新仕様

通常は、偶数バージョンを使用する。

  • ver.6:2016年4月に登場。2018年4月までサポート。2019年4月までメンテナンス。
  • ver.8:2017年5月に登場。2019年1までサポート。2019年12月までメンテナンス。
  • ver.10:2018年4月に登場。2020年4までサポート。2021年4月までメンテナンス。

npm

インストールしたいフォルダに移動して
npm install -g パッケージ名

-gはグローバルオプションでNode.js本体にインストールする。
サーバへアップする場合などは-gを外し、カレントフォルダへインストールする。

WEBサーバを動かす(コマンドライン)

node
.editor
require('http').createServer((rq,rs)=>{rs.end('Hello Node.js!');}).listen(3000);
Ctrl+D
# http://localhost:3000でアクセス可能

nodeの後はjavascript文を実行できる

node
console.log('Hello');

.editorでエディタモードに切り替わる。Ctrl+Dで入力完了、Ctrl+Cでキャンセル。

WEBサーバを動かす(ファイル)

const http = require('http');
var server = http.createServer(
    (request, response)=>{
        response.setHeader('Content-type', 'text/html');
        response.write('<html lang=""ja""><head><meta charset=""utf-8""></head><body>');
        response.write('<hr>ハロー<hr></body></html>');
        response.end();
    }
);
server.listen(3000);

ディレクトリに移動してnode app.jsで実行

Node.jsではrequire(モジュール名)でモジュールを使えるようになる。
最初から使える状態のオブジェクトにしておくと、知らずに同名のオブジェクト名で新たにオブジェクトを作ってしまうかもしれないため。

requestはhttp.ClientRequestオブジェクト
responseはhttp.ServerResponseオブジェクト

fsオブジェクト

  • オブジェクト取得
    var fs = require('fs');
  • 非同期処理でファイル読み込み
    fs.readFile('hello.txt', 'UTF-8', readFinish);
  • 同期処理でファイルを読み込み
    fs.readFileSync('hello.txt', 'UTF-8');

readFileメソッドはどんな大きさのファイルでも即時に実行を終え、次に進む。
実際の読み込みはバックグラウンドで行われ、読み込みが完了したら第3引数の関数を実行する。
そこで読み込み後の処理などを行う、という仕組みになっている。

const http = require('http');
const fs = require('fs');

var server = http.createServer(
    (request, response)=>{
        fs.readFile('hello.html', 'UTF-8', (error, data)=>{
            response.setHeader('Content-type', 'text/html');
            response.write(data.replace(/<hr>/g, '<hr style=""border-color:red"">'));
            response.end();
        });
    }
);
server.listen(3000);

ファイル書き込み

fs.writeFile('data.txt', 'hogehoge', (error)=>{
    if (error) {
        throw error;
    }
});

追記する場合はappendFileメソッドを使う。

EJS

Embedded JavaScript templates
Node.jsのテンプレートエンジンの1つ。
npmコマンドでインストールできる。
npm install -g ejs

  • require('ejs');で読み込み
  • テンプレートファイルは拡張子を.ejsとするのが一般的
  • 変数は<%=hoge %>(エスケープしない場合は<%- %>)
  • ejsオブジェクト.render(ejsテキスト, {変数名: 値}));でHTML取得
const http = require('http');
const fs = require('fs');
const ejs = require('ejs');

var server = http.createServer(
    (request, response)=>{
        data = ejs.render(fs.readFileSync('index.ejs', 'UTF-8'), {name: 'ゲストさん'});
        response.setHeader('Content-type', 'text/html');
        response.write(data);
        response.end();
    }
);
server.listen(3000);

EJSでのループ

<% %>で囲むだけ。

<% for (var key in data) { %>

<% } %>

EJSのパーシャル

  • renderにfilenameという名前でインクルードするパスを指定する
  • <%- include('ファイル名', パラメータ) %>
data = ejs.render(fs.readFileSync('index.ejs', 'UTF-8'), {name: 'ゲストさん', filename: './'});

※filenameはファイル名を入れても無視され、ディレクトリがインクルードパスとして使われる。よって、filename: ‘./aaa.txt’など存在しないファイルを指定しても、./と同じ扱いとなる

ルーティング

http://localhost:3000/hoge.jpgなどとやってもindex.ejs(readFileSyncで読んだファイル)が表示される。
よって、<img src="./hoge.jpg"/>とやっても画像は表示されない。
⇒URLオブジェクトを利用する

  • require('url');で読み込み
  • urlオブジェクト.parse(ClientRequestオブジェクト.url);でパース済みオブジェクトを取得
  • パース済みオブジェクト.pathnameによって分岐させる
const http = require('http');
const fs = require('fs');
const ejs = require('ejs');
const url = require('url');

var server = http.createServer(
    (request, response)=>{
        var parsed_url = url.parse(request.url);
        switch (parsed_url.pathname) {
            case '/':
            data = ejs.render(fs.readFileSync('index.ejs', 'UTF-8'), {name: 'ゲストさん'});
            response.setHeader('Content-type', 'text/html');
            response.write(data);
            response.end();
            break;
        }
    }
);
server.listen(3000);

クエリストリングの取得

  • parseメソッドの第2引数をtrueにする
  • パース済みオブジェクトのqueryプロパティに格納されている
    (parseメソッドの第2引数がfalse(または未指定)だとvar=hogeという文字列になる)
const http = require('http');
const fs = require('fs');
const ejs = require('ejs');
const url = require('url');

var server = http.createServer(
    (request, response)=>{
        var parsed_url = url.parse(request.url, true);
        switch (parsed_url.pathname) {
            case '/other':
            var query = parsed_url.query;
            data = ejs.render(fs.readFileSync('other.ejs', 'UTF-8'), {name: query.name});
        }
    }
);
server.listen(3000);

POST値の取得

  • require('querystring');で読み込み
  • ClientRequestオブジェクト.methodでリクエストメソッドを取得可能
  • ClientRequestオブジェクトのonメソッドでイベントを設定する
    dataイベントが受信時、endイベントが受信完了時
    ※文字列が長い場合には何回かに別れて送られてくるため、dataイベントも複数回コールされる
  • querystringオブジェクト.parse(body);でパース
const querystring = require('querystring');
// ~省略~
switch (parsed_url.pathname) {
    case '/other':
        if (request.method === 'POST') {
            var body = '';
           request.on('data', (data) => {
                body += data;
            });
            request.on('end', () => {
                var params = querystring.parse(body);
                // 処理
            });
        }
}

アプリケーション変数

WEBサーバは実行中の状態で待ち受けているため、グローバル変数は常に保持されている。
よって、グローバル変数はいつ誰がアクセスしても同じ値を得ることができるアプリケーション変数として使うことができる。

var msg = 'no message';
// として
var params = querystring.parse(body);
msg = params.message;
data = ejs.render(fs.readFileSync('./other.ejs', 'UTF-8'), {msg :  msg );

クッキー

// 保存
response.setHeader('Set-Cookie', ['age=30']);
// 取得
var data = request.headers.cookie.split(';');
for (var i in data) {
    console.log(data[i]); // xx=xxという文字列なのでsubstringなどで自力で取り出す
}

値がマルチバイト文字列の場合はencodeURL、decodeURIでエスケープする必要あり。
※escape, unescapeは廃止予定なので使わない

コメント