【Node.js 入門】EJS + Express で Web アプリ開発

Node.js

対象者

  • Node.js で何ができるのか知りたい人
  • Node.js でウェブアプリを作りたい人
  • EJS・Express・Express Generator がわからない人
  • 細かい仕様は後で調べるから、まずは動くソースコードが欲しい人

Node.js とは

  • サーバーサイドで動く Javascript です。
  • Web サーバーとしての役割も持ちます。

サーバーサイドで動くと何が嬉しいの?

サーバーに保存したデータを利用して、動的な Web アプリケーション(Web ページ)が提供可能になります。
例えば下記のとおりです。

動的な Web アプリケーションサーバーに保存したデータ
チャット他の人がチャットに書き込んだ内容
商品のレコメンドユーザーごとの購入履歴
いいね数のカウントいいねの数

上記のサービスを静的な HTML だけで実装すると

サーバーに保存したデータが更新される度に、HTML の内容を手作業で更新しないといけません。更新者は過労で死にます。

上記のサービスをクライアントサイドで実装すると

全てのデータをそれぞれのクライアントに保存して貰う必要があります。知らない人のチャットの内容を自分のハードディスクに保存してくれるクライアントなんていません。

Node.js のインストール

RHEL(CentOS), Mac OS でのインストール方法について紹介します。その他の Linux ディストリビューションでのインストールはここに載ってます。

RHEL (CentOS) に Node.js をインストールする場合

  1. Node.js v12 の nodesource リポジトリをインストールします。
    curl -sL https://rpm.nodesource.com/setup_12.x | sudo bash -

    setup_12.x の “12” の値を変更すると指定したバージョンをダウンロードできます。最新バージョンは下記の GitHub で 「Node.js Current」 と検索すれば出てきます。

    nodesource/distributions
    NodeSource Node.js Binary Distributions. Contribute to nodesource/distributions development by creating an account on GitHub.
  2. Node.js をインストールします。
  3. sudoyum install-y nodejs

Mac OS に Node.js をインストールする場合

下記の記事が参考になります。

MacにNode.jsをインストール - Qiita
MacにNode.jsの環境を構築するメモ。 その前に ※以下の方法もオススメです! MacにNode.jsをインストール(anyenv + nodenv編) 上記の場合はプロジェクト毎(フォルダ毎)にNodeのバージョンを指定...

Node.js を使ってみる

Node.js をインストールしたので、早速 Web アプリケーションを作ってみます。

Hello World を表示する

まずは定番の Hello World から作成します。

  1. Node.js のプログラムを作成します。
  2. vim hello.js
    hello.js の中身は下記のとおりです。
    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);
  3. hello.js をウェブサーバーとして起動します
  4. node hello.js
  5. ウェブブラウザで http://localhost:3000/ にアクセスします

無事に Hello World が表示されました。

パスごとに HTML ファイルを読み込んで表示する

次にパスごとに異なる html ファイルを読み込んで表示してみます。

  1. パスごとに読み込む HTML を変更する Node.js のプログラムを作成します。
  2. vim path.js
    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);
  3. ‘/’ パスで使用する index.html を作成します。
  4. vim index.html
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>title</title>
    </head>
    <body>
        Hello World
    </body>
    </html>
  5. ‘/other.html’ パスで使用する other.html を作成します。
  6. vim other.html
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>title</title>
    </head>
    <body>
        other page
    </body>
    </html>
  7. path.js をウェブサーバーとして起動します
  8. node path.js
  9. ウェブブラウザで http://localhost:3000/, http://localhost:3000/other.html にアクセスします

ちゃんと ‘/’ パスと ‘/other.html’ パスで異なる HTML ファイルを読み込んでいることがわかります。

【Express】 Web アプリケーションフレームワークを使う

Node.js のコードをもっと短く方法ねーのかよ!って思った方。あります!

Express というWeb アプリケーションレームワークを使います。

Webアプリケーションフレームワークって何?

フレームワークとは、雛形の集まりです。
つまり Web アプリケーションフレームワークは Web アプリケーションを作る時に使用する基本機能の雛形の集まりです。

基本機能は毎回同じコードを書くので、雛形として用意してくれているのが Express です。この雛形を使えば数行のコードで必要な機能を実装できます。

Express を使用して、path.js を実装

まずは Express をインストールします。先程 Node.js をインストールした際に、npm と呼ばれる Node.js 用のパッケージ管理ソフトも一緒にインストールされていますので、こちらを利用します。

  1. まずは初期化をします。(モジュールのための仮想環境を作ってます。)
  2. npm init -y
  3. 次に npm を使用して Express をインストールします。
  4. npm install express

    WARN が出ますが、気にしなくてOKです。(気になる方はここ)

  5. Express を使用して Node.js のプログラムを作成します。
  6. vim express.js

    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);
  7. express.js をウェブサーバーとして起動します
  8. node express.js
  9. ウェブブラウザで http://localhost:3000/, http://localhost:3000/other.html にアクセスします

path.js と比較して express.js はかなりソースコードが短くなったことがわかります。

【EJS】動的な Web アプリケーションを作る

今までの方法は、予め作成した静的な HTML を表示しているだけです。これだけならサーバーサイドで処理する必要がありません。ここからは、サーバーサイドで動的に生成する HTML を表示することにします。

動的に HTML を生成するには”テンプレート”を利用します。テンプレートは下記の2つから構成されます。

  • HTML の雛形
  • HTML の雛形に変数を埋め込む機能

テンプレートの変数に値を埋め込んで、動的に HTML を生成することをレンダリングと呼びます。今回はレンダリングするためにテンプレートエンジンとして EJS を利用します。

EJS を利用していいねボタンを実装

  1. npm を使用して EJS をインストール
  2. npm install ejs
  3. EJS と Express を利用していいねボタンを実装
    1. テンプレートを作成
    2. Express でテンプレートファイル(.ejs)を使用する場合 views ディレクトリ配下に置くことになっています。

      mkdir views
      vim ./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 の書き方と同じですね。
      埋め込みを受け付ける変数は<%= “変数名”%>と記載します。

    3. テンプレートを元に HTML を生成するプログラムを作成・表示
    4. いいね数の保存先は data.txt とします。本格的にデータを管理する場合はデータベース(MySQL,PostgreSQLなど)を利用すればいいかと思います。

      vim like.js
      const 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() でレンダリングしています。

  4. like.js をウェブサーバーとして起動します
  5. node like.js
  6. ウェブブラウザで http://localhost:3000/ にアクセスします

いいねボタンと現在のいいね数が表示されました。

いいねボタンをクリックするといいね数が増えていきます。また、別のクライアントからアクセスしても、いいね数は 0 に戻りません。これはサーバーサイドで保存した「いいね数」をレンダリングしているためです。

【Express Generator】Express のスケルトンを作成

.ejs や .js ファイルのスケルトン(雛形)が最初からあればなぁ〜〜〜。って思った方。あります!

Express Generator を使用すれば、Express のスケルトンが自動生成されますので、index.ejs や index.js に追記することで簡単に Web アプリケーションを作ることができます。

Express Generator で Web アプリケーションを立ち上げる

  1. Express Generator をインストール
  2. sudo npm install -g express-generator
  3. Web アプリケーションのスケルトンを作成
  4. express -e <Web アプリケーション名>

    今回はアプリケーション名を myapp とします。

  5. Express Generator が定義したモジュール(package.json 参照)をインストール
  6. cd ./myapp
    npm install
  7. bin/www をウェブサーバーとして起動します
  8. Express Generator では index.js の代わりに bin/www をウェブサーバーとして立ち上げます。
    node bin/www
  9. ウェブブラウザで http://localhost:3000/ にアクセスします

簡単に Web アプリケーションを立ち上げることが出来ました。以下に 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 アプリケーションに先程のいいねボタンを表示するパスを追加してみます。

  1. 「views」ディレクトリに like.ejs ファイルを置きます。
  2. cp ../views/like.ejs ./views/like.ejs
    また、元の like.ejs ファイルから少し修正する必要があります。下記に修正箇所を赤線マーカーで示します。
    <!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>
    
  3. 「routes」ディレクトリに like.js ファイルを置きます。
  4. cp ../like.js ./routes/like.js
    また、元の like.js ファイルから少し修正する必要があります。下記に修正箇所を赤線マーカーで示します。
    vim routes/like.js
    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;
  5. app.js ファイルに下記の赤線マーカーの箇所を追加します
  6. 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;
  7. bin/www をウェブサーバーとして起動します
  8. node bin/www
  9. ウェブブラウザで http://localhost:3000/like にアクセスします

無事 “/like” パスにて先程作成したいいねボタンにアクセスできたことがわかります。

最後に

これまで、以下のことを説明しました。

  • Web アプリケーションフレームワーク Express を使用して簡単に Node.js を書く
  • テンプレートエンジン EJS を使用して動的な Web アプリケーションを作成
  • Express のスケルトン作成には、ツール Express Generator を利用

なお、この記事を執筆するにあたり、下記の書籍を参考にしました。

この記事が 1 人でも多くの人の Node.js の理解の手助けになればいいなと思います。

0

コメント

タイトルとURLをコピーしました