本文へスキップ

gulpでEJSをHTMLにコンパイルする環境を作る

EJSを使う機会があったので、準備の手順をまとめます。EJSは、HTMLの中にJavaScriptを埋め込んで、ヘッダーやフッターなどの共通部分を部品として使い回せるテンプレートエンジンです。

Node.jsとnpmがインストール済みであることを前提とします。

補足

この記事のコードは、gulp 5.0.1、gulp-ejs 5.1.0、gulp-prettier 7.0.0、Node.js 24で動作を確認しています(2026年10月時点)。

package.jsonの作成とパッケージのインストール

package.jsonを作成

ターミナルbash · 1行
npm init -y

インストールするパッケージ

続いて、EJSのコンパイルに必要なnpmのパッケージをインストールします。

パッケージ

役割

gulp

タスクランナー

gulp-ejs

EJSのコンパイル

gulp-rename

コンパイル時に拡張子を.ejsから.htmlに変える

gulp-plumber

エラーが出ても処理を停止しない

gulp-notify

エラーの内容を通知する

gulp-prettier

HTMLを整形する

下記のコマンドでまとめてインストールできます。

ターミナルbash · 1行
npm i -D gulp gulp-rename gulp-ejs gulp-notify gulp-plumber gulp-prettier

以下のコマンドを実行して、gulpが使える状態か確認してください。

ターミナルbash · 1行
npx gulp --version
補足

npxを付けると、プロジェクトにインストールしたgulpを実行できます。npxを付けずにgulpコマンドを使いたい場合は、npm i --global gulp-cliでgulp-cliをインストールしてください。

ファイルを作成する

gulpfile.jsにタスクを書く

プロジェクトの直下にgulpfile.jsを作成し、下記のコードを貼り付けます。

gulpfile.jsJavaScript · 36行
const { src, dest, watch, series } = require('gulp')const rename = require('gulp-rename')const ejs = require('gulp-ejs')const notify = require('gulp-notify')const plumber = require('gulp-plumber')const prettier = require('gulp-prettier').default// EJSをHTMLにコンパイルするconst ejsFunc = () => {  return src(['./src/ejs/**/*.ejs', '!./src/ejs/**/_*.ejs'])    .pipe(      plumber({        errorHandler: notify.onError('Error: <%= error.message %>'),      }),    )    .pipe(ejs())    .pipe(rename({ extname: '.html' }))    .pipe(      prettier({        printWidth: 150,        semi: true,        singleQuote: true,        trailingComma: 'all',      }),    )    .pipe(dest('./'))}// ファイルを監視するconst watchFiles = () => {  watch('./src/ejs/**/*.ejs', ejsFunc)}exports.ejs = ejsFuncexports.watch = watchFilesexports.default = series(ejsFunc, watchFiles)

ファイル名が_で始まるEJS(_header.ejsなど)は、ほかのファイルから読み込む部品として扱い、単体ではHTMLに出力しません。

注意

現在のgulp-prettier(バージョン7)はESモジュールです。requireで読み込む場合は、require('gulp-prettier').defaultのように.defaultを付けます。付けないと「prettier is not a function」というエラーになります。

EJSファイルを作成する

index.ejs、_header.ejs、_footer.ejsにコードを書きます。

src/ejs/index.ejsEJS · 7行
<% let title = "トップページのタイトル" %><%- include('common/_header', { ttl: title }) %>  <p>ページの本文</p><%- include('common/_footer') %>
src/ejs/common/_header.ejsEJS · 8行
<!DOCTYPE html><html lang="ja"><head>  <meta charset="UTF-8">  <meta name="viewport" content="width=device-width, initial-scale=1.0">  <title><%= ttl %></title></head><body>
src/ejs/common/_footer.ejsEJS · 2行
</body></html>

<%- include() %>で別のファイルを読み込みます。第2引数に渡した値(ここではttl)は、読み込まれた側で使えます。<%= %>は値をエスケープして出力し、<%- %>はエスケープせずに出力します。

コンパイルしてみる

gulpfile.jsには、2つのタスクが書かれています。

1度だけコンパイル

ターミナルbash · 1行
npx gulp ejs

ファイルを監視してコンパイル

EJSファイルを保存するたびに、自動でコンパイルします。止めるときはCtrl + Cを押します。

ターミナルbash · 1行
npx gulp watch

出力されたHTMLを見てみる

前述のgulpfile.jsをそのまま貼り付けた場合、プロジェクトの直下にindex.htmlが生成されるので、その中身を確認してみます。gulp-prettierによって整形されたHTMLが出力されます。

index.htmlHTML · 11行
<!doctype html><html lang="ja">  <head>    <meta charset="UTF-8" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>トップページのタイトル</title>  </head>  <body>    <p>ページの本文</p>  </body></html>

JSONを使用する場合の追加対応

サイト名などのデータをJSONファイルにまとめておき、テンプレートの中で使うこともできます。JSONファイルを読み込んで、ejs()の引数に渡します。JSONファイルを変更したときもコンパイルするように、監視の対象にも加えます。

gulpfile.jsJavaScript · 38行
const { src, dest, watch, series } = require('gulp')const rename = require('gulp-rename')const ejs = require('gulp-ejs')const notify = require('gulp-notify')const plumber = require('gulp-plumber')const prettier = require('gulp-prettier').defaultconst fs = require('fs')// EJSをHTMLにコンパイルするconst ejsFunc = () => {  const jsonData = JSON.parse(fs.readFileSync('./src/ejs/json/data.json'))  return src(['./src/ejs/**/*.ejs', '!./src/ejs/**/_*.ejs'])    .pipe(      plumber({        errorHandler: notify.onError('Error: <%= error.message %>'),      }),    )    .pipe(ejs({ jsonData: jsonData }))    .pipe(rename({ extname: '.html' }))    .pipe(      prettier({        printWidth: 150,        semi: true,        singleQuote: true,        trailingComma: 'all',      }),    )    .pipe(dest('./'))}// ファイルを監視するconst watchFiles = () => {  watch(['./src/ejs/**/*.{ejs,json}'], ejsFunc)}exports.ejs = ejsFuncexports.watch = watchFilesexports.default = series(ejsFunc, watchFiles)
src/ejs/json/data.jsonJSON · 3行
{  "siteName": "サイト名"}

テンプレートの中では、jsonDataからデータを取り出せます。

src/ejs/index.ejsEJS · 1行
<p><%= jsonData.siteName %></p>

まとめ

HTMLを効率よく書きたいときに、EJSや他のテンプレートエンジンを使ってみると良いですね。

参考・引用