はじめに
「全ページのヘッダーを修正するのに、また時間がかかりそうだ…」
「共通パーツのコピペ作業、ミスをしないか不安になる…」
「大規模サイトになってきて、HTMLの管理が大変になってきた…」
このような悩みを抱えているWeb制作者の方は多いのではないでしょうか?
特に、制作経験が浅い方や、PHPが使えないレンタルサーバーでの開発を任されている方にとって、複数ページにまたがる共通パーツの管理は大きな課題となっています。
本記事では、EJSという技術を活用して、Web制作の現場で直面する共通課題を解決する方法を、環境構築の基礎から実践的な活用方法まで、順を追って丁寧に解説していきます。
この記事を読むことで得られること
- Node.js + EJSによる効率的な開発環境の構築方法
- 共通パーツの一元管理によるメンテナンス性の向上
- コーディング作業における工数の50%以上の削減
- ミスのない、安定したWeb制作ワークフローの確立
本記事の対象者
本記事は、以下のような基礎知識をお持ちの方を対象としています:
- HTMLとCSSの基本的な理解がある方
- コマンドラインの基本操作ができる方
- JavaScriptの基礎(変数・関数程度)を理解している方
※JavaScriptの知識に不安がある方は、まず当ブログのJavaScriptの記事をご覧いただくことをお勧めします。

1. 開発環境の構築
Node.jsのインストール
まずは開発に必要なNode.jsをインストールします。これがEJSを動かすための土台となります。
Node.jsの公式サイトにアクセスし、「Downloadボタンから」Node.jsをダウンロードしてください。

ダウンロードしたインストーラーを実行してください。
右下の「続ける」を押して手順に従いインストールをしてください。

インストール完了後、お使いのエディタでターミナルを開いてください。

ターミナルで以下のコマンドを実行して確認します。
node -v
npm -v
バージョン番号が表示されれば成功です!

プロジェクトの初期化
ここでは、EJSを使うための「作業場」を準備します。
作業用フォルダの準備
以下の2つのコマンドを実行してください。
mkdir my-ejs-project
cd my-ejs-project
これは「my-ejs-project」という新しい作業フォルダを作って、その中に移動する命令です。
要するに、プロジェクト用の新しい引き出しを作るようなものです。
プロジェクトの初期化
以下のコマンドを実行してください。
npm init -y
このコマンドは、プロジェクトの設定ファイル(package.json)を作ります。-y
オプションをつけると、全ての設定をデフォルトで「はい」と答えてくれます。
これは、引っ越しの時に新しい家の住所や連絡先を登録するようなものです。
必要なツールのインストール
以下の2つのコマンドを実行してください。
npm install ejs express
npm install --save-dev nodemon
ここでは、EJSを使うために必要な3つのツールをインストールしています。
ejs
: HTMLテンプレートを作るための本体express
: 開発用のWebサーバーを立ち上げるためのツールnodemon
: ファイルの変更を監視して自動で更新してくれる便利ツール
基本的なディレクトリ構成
今回は以下のような理由で、それぞれのフォルダを分けています。
my-ejs-project/
├── src/ # 作業用フォルダ(原稿を書くところ)
│ ├── pages/ # 各ページのEJSファイル(各ページの原稿)
│ ├── partials/ # 共通パーツ(よく使う定型文)
│ └── layouts/ # レイアウトテンプレート(原稿の基本フォーマット)
├── public/ # 公開用フォルダ(完成品の置き場所)
├── package.json # プロジェクトの設定ファイル
└── server.js # 開発用サーバーの設定ファイル
この構成の利点は以下の通りです。
- 作業用(src)と公開用(public)が分かれているので、管理が楽
- 共通パーツ(partials)を1箇所にまとめられるので、修正が楽
- レイアウト(layouts)を使い回せるので、新しいページを作るのが楽
開発用サーバーの設定
開発用サーバーを設定する理由は、実際のWebサイトと同じような環境でテストするためです。
VSCodeでプロジェクトを開く
画面上部のメニューバーから「ファイル」をクリックし、表示されるドロップダウンメニューの中から「フォルダを開く」を選択してください。

表示されるフォルダ選択画面で、先ほど作成した「my-ejs-project」フォルダを探します。
通常はユーザーフォルダ直下にあるはずですので、クリックして選択し、「選択」ボタンをクリックし、開いてください。

server.jsファイルの作成
VSCode上で右クリック→[新しいファイル]を選択し、「server.js」というファイルを作成してください

「server.js」に以下のコードをコピー&ペーストしてください。
const express = require('express');
const app = express();
const port = 3000;
// EJSをテンプレートエンジンとして設定
app.set('view engine', 'ejs');
app.set('views', './src/pages');
// 静的ファイルの設定
app.use(express.static('public'));
// ルーティングの設定
app.get('/', (req, res) => {
res.render('index');
});
// サーバーの起動
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
package.jsonの設定
次に、「package.json」を開き、”scripts”の部分を以下のように編集してください。
"scripts": {
"dev": "nodemon server.js",
"start": "node server.js"
}
最初のページ作成
最初のページを作成して、開発環境が正しく動作するか確認します。
トップページの作成
src/pages
フォルダ内にindex.ejs
を作成してください。
以下の内容をコピー&ペーストしてください。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>EJSテスト</title>
</head>
<body>
<h1>Hello EJS!</h1>
<p>開発環境の構築が完了しました!</p>
</body>
</html>

動作確認
ターミナルで以下のコマンドを実行してください。
npm run dev
ブラウザで http://localhost:3000
にアクセスしてください。
「Hello EJS!」というメッセージが表示されれば、開発環境の構築は成功です!

共通パーツの作成
EJSの大きな特徴は、ヘッダーやフッターなどの共通パーツを別ファイルとして管理できることです。
まずは、よく使う共通パーツを作っていきましょう。
ヘッダーの作成
src
フォルダ内にpartials
フォルダを作成してください。

_header.ejs
を作成し、以下のコードをコピー&ペーストしてください。
<header>
<h1>サイトロゴ</h1>
<nav>
<ul>
<li><a href="/">ホーム</a></li>
<li><a href="/about">会社概要</a></li>
<li><a href="/contact">お問い合わせ</a></li>
</ul>
</nav>
</header>
フッターの作成
src/partials
フォルダ内に_footer.ejs
を作成してください。- 以下の内容をコピー&ペーストしてください。
途中経過は以下のようになります。

トップページの修正
src/pages/index.ejs
にパーツ化したheaderとfooterを追加していきます。
index.ejs
を以下の用に修正してください。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>EJSテスト</title>
</head>
<body>
<%- include('../partials/_header') %>
<main>
<h2>メインコンテンツ</h2>
<p>ここにメインコンテンツが入ります</p>
</main>
<%- include('../partials/_footer') %>
</body>
</html>
ここまでできたら、ブラウザを確認してください。
headerとfooterが動作しているのがわかります。

共通レイアウトの作成
共通レイアウトを作ることで、全ページの基本構造を1つのファイルで管理できます。
ヘッダーやフッターを含めた、ページの「テンプレート」を作っていきましょう。
レイアウトファイルの作成
src
フォルダにlayouts
フォルダを作成してください。

layouts
フォルダに_layout.ejs
を作成し、以下のコードをコピー&ペーストしてください。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= title %> | サイト名</title>
</head>
<body>
<%- include('../partials/_header') %>
<main>
<%- content %>
</main>
<%- include('../partials/_footer') %>
</body>
</html>
トップページの書き換え
src/pages/index.ejs
を以下のように書き換えてください。
<%- include('../layouts/_layout', {
title: 'トップページ',
content: `
<h2>メインコンテンツ</h2>
<p>ここにメインコンテンツが入ります</p>
`
}) %>
ブラウザの表示を確認すると、変化がないので実装できていることが確認できます。

ポイント解説
- レイアウトファイルの仕組み
<%= title %>
: 変数titleの値を出力<%- content %>
: HTMLを含む変数contentの値を出力- includeで渡された値が、これらの変数に入ります
変数の渡し方
<%- include('../layouts/_layout', {
title: 'ページタイトル',
content: '内容'
}) %>
- 第1引数:読み込むファイルのパス
- 第2引数:渡したい値をオブジェクトで指定
新しいページの作り方
例えば、会社概要ページを作る場合は以下のようにします。
src/pages/about.ejs
を作成し、以下のコードをコピー&ペーストしてください。
<%- include('../layouts/_layout', {
title: '会社概要',
content: `
<h2>会社概要</h2>
<dl>
<dt>会社名</dt>
<dd>サンプル株式会社</dd>
<dt>所在地</dt>
<dd>東京都...</dd>
</dl>
`
}) %>
次に以下のコードをserver.js
に追加してください。
// aboutページのルーティング
app.get('/about', (req, res) => {
res.render('about');
});
これで、http://localhost:3000/about
でアクセスできるようになります。
まとめ
この記事では、HTMLの共通パーツを効率的に管理するためのEJSの基本的な使い方を解説しました。
これらの手法を使うことで、共通部分の修正を1箇所で管理できるようになり、新規ページの追加も簡単になります。
結果として、HTMLの保守性が大幅に向上するはずです。
また、最近では新しい選択肢として「Astro」というフレームワークも注目を集めています。
Astroは、EJSの持つテンプレート機能に加えて、以下のような魅力的な特徴を備えています:
- 高速なパフォーマンス(ゼロJavaScriptがデフォルト)
- Reactなどの人気フレームワークとの互換性
- より直感的なコンポーネント管理
- ビルトインの最適化機能
EJSで学んだテンプレート管理の考え方は、Astroを学ぶ際にも大いに役立ちます。
Astroに興味を持たれた方は、ぜひ以下の「実践で使えるAstroの基礎から応用まで完全解説」をご覧ください。

今回紹介したEJSの手法を参考に、ぜひご自身のプロジェクトで実践してみてください。
分からないことがあれば、公式ドキュメントも参考になりますので、確認してみてください。
関連記事

