この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:4
ページ更新者:T
更新日時:2026-06-11 07:10:02

タイトル: インストール
SEOタイトル: EJSインストール完全ガイド(Express連携/Webpack/include/本番ビルド)

この記事の要点
  • EJS = Embedded JavaScript Templates。Node.js で広く使われるテンプレートエンジン
  • インストール: npm install ejs または yarn add ejs
  • Express では app.set("view engine", "ejs") + views ディレクトリで自動連携
  • <%- include("partials/header") %> でパーシャル再利用、共通レイアウト構築
  • Webpack / Vite では ejs-loadervite-plugin-ejs で SPA 内に取り込み可能
  • 本番では テンプレートキャッシュcache: true)と事前コンパイルejs.precompile)で高速化
  • 注意: <%= %> は自動エスケープ、生 HTML 埋め込みは <%- %>(XSS 注意)

EJS とは

EJS(Embedded JavaScript Templates)は HTML の中に <% %> で JavaScript を埋め込めるテンプレートエンジンです。文法が PHP / ASP に近く、学習コストが低いのが特徴。Express の標準的な選択肢として広く使われています。

インストール

# npm
npm install ejs

# yarn
yarn add ejs

# pnpm
pnpm add ejs

# バージョン確認
npm list ejs
# ejs@3.1.10

単体での使い方(Express なしで素の Node.js)

const ejs = require('ejs');

// 文字列テンプレート
const tmpl = '<h1>Hello, <%= name %>!</h1>';
const html = ejs.render(tmpl, { name: 'Alice' });
console.log(html);
// <h1>Hello, Alice!</h1>

// ファイルから
ejs.renderFile('./views/index.ejs', { user: 'Bob' }, (err, str) => {
  console.log(str);
});

// Promise 版
const html2 = await ejs.renderFile('./views/index.ejs', { user: 'Bob' });

Express での連携

const express = require('express');
const path = require('path');
const app = express();

// view engine 設定
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));

// ルーティングから render
app.get('/', (req, res) => {
  res.render('index', {
    title: 'Top Page',
    items: ['apple', 'banana', 'cherry'],
  });
});

app.listen(3000);

ファイル配置例:

project/
├── package.json
├── app.js
└── views/
    ├── index.ejs
    └── partials/
        ├── header.ejs
        └── footer.ejs

EJS テンプレート構文

<!-- views/index.ejs -->
<!DOCTYPE html>
<html>
<head>
  <title><%= title %></title>           <!-- HTMLエスケープあり -->
</head>
<body>
  <%- include('partials/header') %>     <!-- パーシャル取り込み -->

  <h1><%= title %></h1>

  <%# コメント(出力されない) %>

  <ul>
    <% items.forEach((item) => { %>
      <li><%= item %></li>
    <% }) %>
  </ul>

  <% if (user) { %>
    <p>Welcome, <%= user.name %></p>
  <% } else { %>
    <p>Please log in</p>
  <% } %>

  <%- include('partials/footer') %>
</body>
</html>

タグの種類

タグ意味注意
<% code %>JS 実行(出力なし)制御構文に
<%= value %>値を HTML エスケープして出力★ 通常はこれ
<%- value %>値をエスケープせず出力XSS 注意、include で利用
<%# comment %>コメント(出力されない)
<%% %%>エスケープしてリテラル <% %> を出力
-%>末尾改行を抑制

パーシャル / レイアウト

EJS 自体にはレイアウト機能がありませんが、include でパーシャル構造を作れば代替できます:

<!-- views/partials/header.ejs -->
<header>
  <h1>My Site</h1>
  <nav>
    <a href="/">Home</a> | <a href="/about">About</a>
  </nav>
</header>

<!-- views/partials/layout.ejs -->
<!DOCTYPE html>
<html>
<head><title><%= title %></title></head>
<body>
  <%- include('header') %>
  <main><%- body %></main>
  <%- include('footer') %>
</body>
</html>

<!-- views/index.ejs から layout 経由で render -->

あるいは express-ejs-layouts パッケージで master layout を自動適用できます:

const expressLayouts = require('express-ejs-layouts');
app.use(expressLayouts);
app.set('layout', 'layout');  // views/layout.ejs を共通レイアウトに

Webpack / Vite との連携

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.ejs$/,
        use: ['ejs-loader'],
      },
    ],
  },
};

// 利用
import tmpl from './template.ejs';
document.getElementById('app').innerHTML = tmpl({ user: 'Alice' });
// vite.config.js
import { defineConfig } from 'vite';
import { ViteEjsPlugin } from 'vite-plugin-ejs';

export default defineConfig({
  plugins: [
    ViteEjsPlugin({
      title: 'My App',
      env: process.env.NODE_ENV,
    }),
  ],
});

本番ビルドの最適化

// Express でテンプレートキャッシュ ON
app.set('view cache', true);

// 直接 ejs API でキャッシュ有効化
const html = ejs.render(tmpl, data, {
  cache: true,
  filename: 'index.ejs',   // cache key
});

// 事前コンパイル(CI でビルド時に実行)
const fn = ejs.compile(fs.readFileSync('index.ejs', 'utf8'));
fs.writeFileSync('index.js', `module.exports = ${fn.toString()};`);

// 利用時
const tmplFn = require('./index.js');
const html2 = tmplFn({ user: 'Bob' });

XSS 対策と escape

<%# ✅ 自動エスケープ %>

<%= userInput %>

<%# ❌ エスケープせず(XSS 危険!) %>

<%- userInput %>

<%# ✅ include の中身は HTML としてそのまま出したいので - を使う %> <%- include('partials/header') %> <%# 自前 sanitize %> <% const safe = require('dompurify').sanitize(userHtml); %> <%- safe %>

FAQ

Q: EJS と Pug、Handlebars どれを選ぶ?
A: HTML をそのまま書きたい / 学習コスト低い → EJS。インデント記法でタイプ量を減らしたい → Pug。ロジックレスを徹底したい → Handlebars / Mustache。

Q: フロントエンド(React / Vue)と併用できる?
A: 可能。EJS はサーバ側の HTML 骨格生成、React/Vue は SPA 側。あるいは EJS は完全に外して全部 React/Vue にする選択も。

Q: ホットリロードしたい
A: 開発時は view cache を OFF、nodemon で .ejs 変更時に再起動。