本記事は以下の書籍を参考にしています。
対象者
- Node.js でウェブアプリを作りたい人
- EJS・Express・Express Generator がわからない人
- 細かい仕様は後で調べるから、まずは動くソースコードが欲しい人
Node.js とは
- サーバーサイドで動く Javascript です。
- Web サーバーとしての役割も持ちます。
サーバーサイドで動くと何が嬉しいの?
サーバーに保存したデータを利用して、動的な Web アプリケーション(Web ページ)が提供可能になります。
例えば下記のとおりです。
動的な Web アプリケーション | サーバーに保存したデータ |
---|---|
チャット | 他の人がチャットに書き込んだ内容 |
商品のレコメンド | ユーザーごとの購入履歴 |
いいね数のカウント | いいねの数 |
上記のサービスを静的な HTML だけで実装すると
サーバーに保存したデータが更新される度に、HTML の内容を手作業で更新しないといけません。更新者は過労で死にます。
上記のサービスをクライアントサイドで実装すると
全てのデータをそれぞれのクライアントに保存して貰う必要があります。知らない人のチャットの内容を自分のハードディスクに保存してくれるクライアントなんていません。
【Node.js】Web アプリケーションを作成
Node.js のインストール
RHEL(CentOS), Mac OS でのインストール方法について紹介します。その他の Linux ディストリビューションでのインストールはここに載ってます。
RHEL (CentOS) に Node.js をインストールする場合
- Node.js v12 の nodesource リポジトリをインストールします。 curl -sL https://rpm.nodesource.com/setup_12.x | sudo bash -
setup_12.x の "12" の値を変更すると指定したバージョンをダウンロードできます。最新バージョンは下記の GitHub で 「Node.js Current」 と検索すれば出てきます。
https://github.com/nodesource/distributions/blob/master/README.md
- Node.js をインストールします。 sudo yum install -y nodejs
- Node.js がインストールできていることを確認
$ node -v v12.18.3
Mac OS に Node.js をインストールする場合
下記の記事が参考になります。
Node.js をインストールしたので、早速 Web アプリケーションを作ってみます。
Hello World を表示
定番の Hello World から作成します。
- Node.js のプログラムを作成します。vim hello.js
- hello.js をウェブサーバーとして起動します
- ウェブブラウザで http://localhost:3000/ にアクセスします
const http = require('http'); const server = http.createServer((req,res)=>{ res.writeHead(200,{'Content-Type':'text/html'}); res.write("Hello World");//表示するHTMLを指定 res.end(); }); server.listen(3000);
無事に Hello World が表示されました。
パスごとに異なる HTML ファイルを表示
次にパスごとに異なる html ファイルを読み込んで表示してみます。
- Switch 文を利用してパスごとに異なる html ファイルを表示する Node.js のプログラムを作成します。
- '/' パスで使用する index.html を作成します。
- '/other.html' パスで使用する other.html を作成します。
- path.js をウェブサーバーとして起動します
- ウェブブラウザで http://localhost:3000/, http://localhost:3000/other.html にアクセスします
const http = require('http'); const fs = require('fs'); const url = require('url') const server = http.createServer((req,res)=>{ var path = url.parse(req.url).pathname switch (path){ //パスごとに読み取るファイルを変更 case '/': fs.readFile('./index.html','UTF-8',(err,data)=>{ res.writeHead(200,{'Content-Type':'text/html'}); res.write(data); //読み取ったHTMLをレスポンスで使用 res.end(); }); break; case '/other.html': fs.readFile('./other.html','UTF-8',(err,data)=>{ res.writeHead(200,{'Content-Type':'text/html'}); res.write(data); //読み取ったHTMLをレスポンスで使用 res.end(); }); break; } }); server.listen(3000);
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>title</title> </head> <body> Hello World </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>title</title> </head> <body> other page </body> </html>
ちゃんと '/' パスと '/other.html' パスで異なる HTML ファイルを読み込んでいることがわかります。
【Express】 Web アプリケーションフレームワーク
Node.js のコードをもっと短く方法ねーのかよ!って思った方。あります!
Express という Web アプリケーションレームワークを使います。
Express でパスごとに異なる HTML ファイルを表示
まずは Express をインストールします。先程 Node.js をインストールした際に、npm と呼ばれる Node.js 用のパッケージ管理ソフトも一緒にインストールされていますので、こちらを利用して Express をインストールします。
- まずは初期化をします。(モジュールのための仮想環境を作ってます。)
- 次に npm を使用して Express をインストールします。
- Express を使用して Node.js のプログラムを作成します。
- express.js をウェブサーバーとして起動します
- ウェブブラウザで http://localhost:3000/, http://localhost:3000/other.html にアクセスします
WARN が出ますが、気にしなくてOKです。(気になる方はここ)
Express は require('express') で Express モジュールを作成するだけで使えます。
const express = require('express') const app = express() app.get('/', (req, res) => { res.sendFile(__dirname + '/index.html'); }); app.get('/other.html', (req, res) => { res.sendFile(__dirname + '/other.html'); }); app.listen(3000);
Express を利用しない場合と比較して Express を利用するとかなりソースコードが短くなったことがわかります。
【EJS】テンプレートエンジン
今までの方法は、予め作成した静的な HTML を表示しているだけです。これだけなら Node.js を利用してサーバーサイドで処理する必要がありません。ここからは、EJS を利用してサーバーサイドで動的に HTML ファイルを生成します。
動的に HTML を生成するにはテンプレートを利用します。テンプレートは下記の2つから構成されます。
- HTML の雛形
- HTML に埋め込んだ変数
テンプレートの変数に値を埋め込んで、動的に HTML を生成することをレンダリングと呼びます。EJS はテンプレートをレンダリングするためのテンプレートエンジンです。
EJS を利用していいねボタンを実装
- npm を使用して EJS をインストール
- EJS と Express を利用していいねボタンを実装
- テンプレートを作成
- テンプレートを元に HTML を生成するプログラムを作成・表示
Express でテンプレートファイル(.ejs)を使用する場合 views ディレクトリ配下に置くことになっています。
mkdir viewsvim ./views/like.ejs<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>title</title> </head> <body> <form action="/" method="post" > <input type="submit" value="いいね"> <%= like%> </form> </body> </html>
EJS のテンプレートファイルはほとんど HTML の書き方と同じですね。
埋め込みを受け付ける変数は<%= "変数名"%>と記載します。いいね数の保存先は data.txt とします。本格的にデータを管理する場合はデータベース(MySQL,PostgreSQLなど)を利用すればいいかと思います。
vim like.jsconst ejs = require('ejs'); const fs = require('fs'); const express = require('express') const app = express() var like; try { //いいねデータがあれば読み込み。なければいいねが0 like = fs.readFileSync('./data.txt','UTF-8'); } catch(err){ like = 0; } app.engine('ejs',ejs.renderFile); app.get('/', (req, res) => { res.render('./like.ejs',{like:like}); }); app.post('/', (req, res) => { //いいねボタンをクリックした時 like++; fs.writeFileSync('./data.txt',String(like)); res.render('./like.ejs',{like:like}); }); app.listen(3000);
テンプレートに埋め込んだ変数"like"に対して res.render() でレンダリングしています。
- like.js をウェブサーバーとして起動します
- ウェブブラウザで http://localhost:3000/ にアクセスします
いいねボタンと現在のいいね数が表示されました。
いいねボタンをクリックするといいね数が増えていきます。また、別のクライアントからアクセスしても、いいね数は 0 に戻りません。これはサーバーサイドで保存した「いいね数」をレンダリングしているためです。
【Express Generator】Express のスケルトンを作成
.ejs や .js ファイルのスケルトン(雛形)が最初からあればなぁ〜〜〜。って思った方。あります!
Express Generator を使用すれば、Express のスケルトンが自動生成されますので、index.ejs や index.js に追記することで簡単に Web アプリケーションを作ることができます。
Express Generator で Web アプリケーションを立ち上げる
- Express Generator をインストール
- Web アプリケーションのスケルトンを作成
- Express Generator が定義したモジュール(package.json 参照)をインストール
- bin/www をウェブサーバーとして起動します Express Generator では index.js の代わりに bin/www をウェブサーバーとして立ち上げます。
- ウェブブラウザで http://localhost:3000/ にアクセスします
今回はアプリケーション名を myapp とします。
Express Generator で生成した各ディレクトリの説明
- 「bin」: Web アプリケーション実行用のファイルを保管
- 「node_modules」: npm install でインスタンスしたモジュールをここに保管
- 「public」:クライアントに公開する javascript, css, image ファイルを保管
- 「routes」:パスごとのスクリプトファイル (.js) を保管
- 「views」:パスごとのテンプレートファイル (.ejs) を保管
- 「app.js」: Web アプリケーションの本体
- 「package.json, package-lock.json」: npm がモジュールの管理に利用
Express Generator で生成した Web アプリケーションにパスを追加する
Express Generator で生成した Web アプリケーションに先程のいいねボタンを表示するパスを追加してみます。
- 「views」ディレクトリに like.ejs ファイルを置きます。
- 「routes」ディレクトリに like.js ファイルを置きます。
- app.js ファイルに下記の赤線マーカーの箇所を追加します
- bin/www をウェブサーバーとして起動します
- ウェブブラウザで http://localhost:3000/like にアクセスします
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title</title>
</head>
<body>
<form action="/like" method="post" >
<input type="submit" value="いいね"> <%= like%>
</form>
</body>
</html>
const ejs = require('ejs'); const fs = require('fs'); const express = require('express') var app = express.Router(); var like; try { //いいねデータがあれば読み込み。なければいいねが0 like = fs.readFileSync('./data.txt','UTF-8'); } catch(err){ like = 0; } app.get('/', (req, res) => { res.render('./like.ejs',{like:like}); }); app.post('/', (req, res) => { //いいねボタンをクリックした時 like++; fs.writeFileSync('./data.txt',String(like)); res.render('./like.ejs',{like:like}); }); module.exports = app;
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 likeRouter = require('./routes/like'); 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); app.use('/like', likeRouter); // 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;
無事 "/like" パスにて先程作成したいいねボタンにアクセスできたことがわかります。
最後に
これまで、以下のことを説明しました。
- Web アプリケーションフレームワーク Express を使用して簡単に Node.js を書く
- テンプレートエンジン EJS を使用して動的な Web アプリケーションを作成
- Express のスケルトン作成には、ツール Express Generator を利用
この記事が 1 人でも多くの人の Node.js の理解の手助けになればいいなと思います。
■関連記事