10
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

EJSの基本の使い方と、今後のゆくえ(2020~)

Last updated at Posted at 2020-12-21

2020年12月19・20日に調べた
EJS(テンプレートエンジン)の使い方と
EJSの今後(2020〜)について考察しました
想定としては、React, Angular, Vue を覚える前のサーバ初心者が
Node + Express を使って
サーバ側でレンダリングを気軽にやってみたいなと思った時に
EJSで手軽に出来るよ、という内容です

2020年12月21日 1回目更新
2020年12月28日 2回目更新

目次

  1. 始めに
  2. サーバ側の事前準備
  3. タグ
  4. include()
  5. EJSの今後
  6. まとめ

始めに

この記事で

想定している事

  • JavaScript(DOM)はある程度書ける
  • HTMLを5〜30分程でレンダリングする
  • Node + Express を使ってサーバ側でレンダリングする
  • 基本タグ(<%# %>,<% %>,<%= %>,<%- %>)を足すだけなので学習コストが低い
  • ローカルサーバ側でのinclude(パス、オブジェクト値)の使い方も簡単に紹介します
  • ローカルサーバ側のオブジェクト値が、クライアント側に送れているかを確認する

想定していない事

  • 複雑な事や中〜大規模な事は React, Angular, Vue で覚えて下さい
  • 複数ではなく、1ページのみのレンダリングを想定しています
  • gulpは使いません
    • 代わりに nodemon でレンダリングの自動更新を行います

環境

ubuntu     18.04
conda      4.8.4
code      1.52.1

node      12.4.0
express   4.16.1
ejs        3.1.5

サーバ側の事前準備

サーバ環境構築は下記の記事を参考にしてみて下さい

(node, npm は既にインストールされている事とします)

ターミナルで express nodemon ejs をインストールして

Terminal

$ mkdir myFirstEJSapp
$ cd myFirstEJSapp
$ npm init -y
$ npm install --save express nodemon ejs

index.js ファイルを作り、最低限の設定をします

index.js

const express = require('express') // expressを準備
const app = express()
const port = 3000

// express に ejs のテンプレートエンジンを設定
app.set("view engine", "ejs");

// express に ejs のテンプレートエンジンを設定した場合
// /views フォルダが index.ejs のデフォルトになります

app.get("/", function (req, res) {
  res.render("index"); // これで /views/index.ejs をレンダリング
});

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

次に、 package.json ファイルに "start": "nodemon ./index.js"
を加えて、 npm start で nodemon が起動する様にします

package.json
{
  "name": "myFirstEJSapp",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "nodemon ./index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "ejs": "^3.1.5",
    "express": "^4.17.1",
    "nodemon": "^2.0.6"
  }
}

次に、 index.ejs ファイルを views フォルダ内に作成します

views/index.ejs
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>myFirstEJSapp</title>
  </head>
  <body>
    <div>
      テスト
    </div>
  </body>
</html>

今の段階で

myFirstEJSapp (root)
--- node_modules
--- views
------ views/index.ejs
--- index.js
--- package-lock.json
--- package.json

といった構成になります

この段階で
ターミナルで npm start とやると
nodemon(自動更新)が作動し
index.ejs が、サーバ側からレンダリングされた状態で
http://localhost:3000 にローカルサーバが構築されています

もしローカルサーバを構築するのも大変な人は、
ここまでで疲れてしまう人もいるかもしれませんが
ここまで来れば、ほぼ終わったも同然ですので頑張ってみて下さい

EJSの使い方

ここからEJSの使い方を紹介していきます

タグ

この記事では
基本的な4つのタグの使い方を紹介していきます
タグは全て index.ejs, 若しくは他の xxx.ejs 内で使っていく事を想定しています

<元ネタ>

基本タグ四種

  1. <%# %> コメント用タグ
  2. <% %> コード用タグ
  3. <%= %> 出力用タグ(タグはエスケープ)
  4. <%- %> 出力用タグ(タグ込)

下記は省略

  • <%_
  • <%%
  • %%>
  • %>
  • -%>
  • _%>

もしローカルサーバを構築出来なかった人・今は手元にない人でも
オンラインでコードをテスト出来る、下記サイトを使ってみて下さい

左側がサーバ
右側がクライアント
になります

1. <%# %> コメント用タグ

先ず、最初に紹介したいのは
<%# %> コメント用タグで
HTML(クライアント)側からは見られない
サーバ側だけが読めるコメントになります

これは
javascript で言う所の // コメント
HTML で言う所の <!-- コメント -->
になります

先ずは下記リンクで

サンプルコード
<%# これはコメント用 %>

と試してみて下さい
クライアント側には何も表示されない筈です

index.ejs内(サーバ側)でも
<%# これはコメント用 %> が見られますが

index.ejs
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>myFirstEJSapp</title>
  </head>
  <body>
    <div>テスト</div>
    <%# これはコメント用 %>   <--- サーバ側からは見られる
  </body>
</html>

ローカルサーバ ( http://localhost:3000 ) の
クライアント側 ( index.html ) からは
何も表示されません

index.html
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>myFirstEJSapp</title>
</head>
  <body>
    <div>テスト</div>
              <--- クライアント側からは見られません
  </body>
</html>

2. <% %> コード用タグ

次に紹介したいのが
<% %> コード用タグ

通常 HTML の DOM を操作したい場合は
JavaScript のコードを <script></script> タグ内にコードを書いていきますが
EJS で HTML をレンダリングしたい時は <script></script> タグを使わず
<% %> タグを使って JavaScript コードを書いていきます

ここでのポイントは
最終的なゴールは
<% %>内で定義した代数(例: const daisu = "代数")や関数を
<%= %>, <%- %> に出力して
HTML上 (クライアント側) で見られるようにする事です

例えば
下のサンプルコードの様に
先ずは <% %> 内で test_code という代数を定義して
<%= %> 内で "このコードが見られます" という出力を出します

サンプルコード
<%# 下記で代数を定義します %>
<% const test_code = "このコードが見られます"  %>
<%= test_code  %>

先ずは
下記リンクで上記のコードがどんな風に出力されているか試してみて下さい

次に
index.ejs(サーバ側)で下記の様に書くと

index.ejs
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>myFirstEJSapp</title>
  </head>
  <body>
    <div>テスト</div>
    <%# 下記で代数を定義します %>
    <% const test_code = "このコードが見られます" %>

    <%= test_code %>      <--- ここの内容しかHTML上では見られません
  </body>
</html>

HTML上(クライアント側)に出力されているのは
<%= %>
内の部分だけになり
他のコードは見られません

index.html
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>myFirstEJSapp</title>
</head>
  <body>
    <div>テスト</div>
    "このコードが見られます"
  </body>
</html>

3-4. 出力用タグ(<%= %><%- %>)の違い

<% %> タグ内で定義した代数を
<%= %> タグ内で出力出来る様になりました

次は
<%= %> タグと <%- %> タグの違いについて説明していきます

<%= %> はタグ内で定義したタグをエスケープして出力する
<%- %> はタグ内で定義したタグをエスケープしないで出力する

サンプルコードで説明すると

上記のリンクで、下記のサンプルコードを試すと

サンプルコード
<%# 下記で代数を定義します %>
<% const test_code = "<p>このコードが見られます<p>"  %>
<%= test_code  %>

&lt;p&gt;このコードが見られます&lt;p&gt;

( <> がエスケープされて上記の状態になる)

といった出力になるのに対して

下記のサンプルコードを試すと

サンプルコード
<%# 下記で代数を定義します %>
<% const test_code = "<p>このコードが見られます<p>"  %>
<%- test_code  %>

<p>このコードが見られます<p>

という風に<p>タグや色んなタグを出力出来るようになり
HTMLの見た目をサーバ側から弄ることが出来るようになります

なのでEJS上で
<>タグが使いたい場合は<%- %>
オブジェクト値を確認したり、純粋な出力の値だけを確認したい場合は<%= %>
と使い分ける事が出来ます

include()

include() の使い方を簡単に説明すると、
index.ejs 外で取得した代数値やオブジェクト値を
index.ejs 外のテンプレート (template.ejs) を使って
index.ejs 内で表現したい時に役立ちます

これは例えば
サーバ側で fetch や Twitter API 等を使って
オブジェクト値 (ツイート情報) を取得した時に
index.ejs に Twitter のツイートを表現したい(埋め込んだ様に見せたい)時に
簡単に導入する方法です

構文は

incldue(パス, オブジェクト値)

でオブジェクト値は無くても大丈夫です
パスも index.ejs で無くても
ejs を省略して
index だけでもOKです


例えば下記の様な階層だとします

myFirstEJSapp (root)
--- node_modules
--- views
------ views/index.ejs
------ views/template.ejs
--- index.js
--- package-lock.json
--- package.json

そこで
views/index.ejs が下記の様だったとします

views/views/index.ejs
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>myFirstEJSapp</title>
  </head>
  <body>
    <%- include("./template") %>  <--- template.ejs からテンプレートを取得してきます
  </body>
</html>

すると
サーバ側 ( index.js や 自作API ) で fetch や request や Twitter API 等で
オブジェクト値 (ツイート情報) を取得して

index.js
const express = require("express"); // expressを準備
const app = express();
const port = 3000;

// express に ejs のテンプレートエンジンを設定
app.set("view engine", "ejs");

// express に ejs のテンプレートエンジンを設定した場合
// /views フォルダが index.ejs のデフォルトになります

// Twitter API でオブジェクト値(ツイート文)を取得したものと想定します
let data = {
  tweet1: "これは、ツイート1です", 
  tweet2: "これは、ツイート2です",
  tweet3: "これは、ツイート3です",
};

// 取得したオブジェクト値 ( data ) を views/index.ejs に送っています
app.get("/", function (req, res) {
  res.render("index", data); // これで /views/index.ejs をレンダリング
});

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`);
});

オブジェクト値や代数値を
自分の使いたいテンプレートページ (template.ejs) に落とし込んで行きます

下記のテンプレートファイル (template.ejs) に
自分が表現したい書き方をして下さい

views/template.ejs
<div>
  <h3>テスト1</h3>
</div>

<%# 下記のオブジェクト値をindex.ejs外から挿入変更します %>
<%= tweet1 %>   <--- この値はサーバ側(index.js)から送られています
<p></p>

<div>
  <h3>テスト2</h3>
</div>

<%# 下記のオブジェクト値をindex.ejs外から挿入変更します %>
<%= tweet2 %>   <--- この値はサーバ側(index.js)から送られています
<p></p>

<div>
  <h3>テスト3</h3>
</div>

<%# 下記のオブジェクト値をindex.ejs外から挿入変更します %>
<%= tweet3 %>   <--- この値はサーバ側(index.js)から送られています
<p></p>

こうする事によって
サーバ側から取得したオブジェクト値(ツイート文)を
自分の描きたいテンプレートに代入して
それを下記の様に index.html に表現が出来るようになります

index.html
<body>
    <div>
      <h3>テスト1</h3>
    </div>
    これは、ツイート1です
    <p></p>

    <div>
      <h3>テスト2</h3>
    </div>
    これは、ツイート2です
    <p></p>

    <div>
      <h3>テスト3</h3>
    </div>
    これは、ツイート3です
    <p></p>
</body>

今後

2020年12月現在
Qiitaサイト内で
EJS ( 又はテンプレートエンジン ) についての記事を調べていると
勢いがあったのは大体2-4年前までの記事な気がしました

下記の英語の質問箱を見ると

Are template engines still relevant in 2020? - DEV

原因としては
React, Vue, Angular の登場でテンプレートエンジン自体が下火になっている説
フロントエンドの方が人気でバックエンドはあまり人気が無い説
もうテンプレートエンジンの機能をアップデートする必要性があまり無い説
があるそうです

そこで
2020年現在
テンプレートエンジンを使うメリットを考えてみると

  • サーバ側での小規模、パイロットプロジェクトをテスト・デバッグが簡単に出来る
  • JAM (JavaScript, API, Markup) stack 人気がきている

といった利点があるらしいです

JAM stackとは (Qiita 記事@ozaki25)

なので
サーバ初心者、特にレンダリングが良く分からない
React, Angular, Vue を触る前の

サーバ側からどうやってHTMLをレンダリングしているか、試しにいじってみたい人用に
Single Page Application (SPA) 用の1ページだけのアプリを簡単に作って見たい人用に
ちょっと小規模テスト・デバッグ用に使いたい人用に
EJS、他テンプレートエンジンは使い勝手が良いのかな?
と思いました

Qiita - SPAの基本

まとめ

まとめると
現在、EJSの使用利点は段々と限られてきていて(React等のフレームワークに代替してきて)
主力としてのレンダリングツールとしてはテンプレートエンジンの役目ではなくなってきています

ですが
<%= %>,<%- %>出力タグを使って、外部APIの値が取得出来てるかどうかをHTML上で確認したり
include(パス, オブジェクト値)を使ってテンプレ表現をちゃんと実装出来るかどうかテストしてみる
といった小規模のミニプロジェクトを軽く試してみたい場合は
EJSは学習コスト・レンダリングコストが低く
5〜30分ぐらいで大体実装出来てしまいます

そんなEJS活用方法は
React, Angular, Vue 触る前のサーバ初心者には
重宝するのではないでしょうか?

Qiita内トップEJS記事まとめ(2020)

3年以内

テンプレートエンジンEJSで使える便利な構文まとめ - Qiita

@y_hokkey
2017年02月02日に更新

EJSの基本的な書き方 - Qiita

@miwashutaro0611
2018年06月23日

Expressにおけるejsの使い方 - Qiita

@kamihork
2018年10月07日に更新


3年以上前

gulpで手軽にEJSテンプレートをHTMLに変換 - Qiita

@yuichiroharai
2014年10月15日に更新

ejsでextendっぽいことをする方法 - Qiita

@fnobi
2013年07月25日

EJS+gulpで静的サイトのHTML生成 - Qiita

@oden
2016年03月15日


TOP テンプレートエンジン (2020)

"JavaScript template engine 2020"とググった時に出てきた
人気 JavaScript テンプレートエンジン 6 (2020)

. Pug (Jade) Handlebars Mustache doT EJS Nunjucks
記事数 11 10 9 9 8 8
npm LINK LINK LINK LINK LINK LINK
github LINK LINK LINK LINK LINK LINK
Licenses MIT MIT MIT MIT Apache-2.0 BSD-2-Clause
Dependecies 8 5 0 0 1 4
Weekly Downloads 1,121,333 7,265,726 1,933,955 240,792 8,145,826 294,753
Unpacked Size 59.7 kB 2.72 MB 113 kB 73.8 kB 134 kB 1.74 MB
npm内: 人気 61% 67% 60% 33% 80% 47%
npm内: 質 63% 63% 63% 75% 62% 93%
npm内: メンテ 28% 33% 33% 47% 33% 33%
npm collaborator 2 5 3 2 1 5
github star 19.8k 15.7k 14.3k 4.6k 5.1k 7.1k
github used by 286k 3m 215 14.1k - 121k
github contributor 248 175 110 13 113 137

ソース記事

10
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?