12k
All articles

JavaScript テンプレートエンジンの選び方

Node.jsのサーバーサイドHTML生成でEJS、Handlebars、Pug、Nunjucksを比較。構文、用途、セキュリティの要点を解説。

OpenReplay Team
OpenReplay Team
JavaScript テンプレートエンジンの選び方

あなたは Node.js アプリケーションを構築しているとしましょう。管理ダッシュボード、トランザクションメールシステム、あるいは軽量なコンテンツサイトかもしれません。React は必要ありません。サーバー側で HTML をレンダリングしてブラウザに送信するだけで十分です。まさにそのような場面で、JavaScript テンプレートエンジンが真価を発揮します。

この記事では、最も実用的な選択肢である EJSHandlebarsPugNunjucks を比較し、考えすぎずにプロジェクトに最適なものを選べるようにします。

重要なポイント

  • テンプレートエンジンはサーバー側で HTML をレンダリングするため、フルスタックのフロントエンドフレームワークではオーバースペックとなる管理ダッシュボード、メールシステム、コンテンツ主体のサイトに最適です。
  • EJS は JavaScript 開発者にとって最も導入しやすく、Handlebars はロジックとプレゼンテーションをきれいに分離することを強制します。
  • Pug は簡潔でインデントベースの構文と、ネイティブのテンプレート継承を提供し、Nunjucks は複雑なレイアウトのための Jinja2 スタイルの機能を提供します。
  • XSS やテンプレートインジェクションを防ぐため、常にデフォルトでエスケープされる出力タグを使用し、信頼できないコンテンツに対する生の HTML レンダリングは避けてください。

テンプレートエンジン vs フロントエンドフレームワーク

選択肢を比較する前に、重要な区別があります: テンプレートエンジンと、React、Vue、Svelte のようなコンポーネントベースのフレームワークは、異なる問題を解決します。 フレームワークはブラウザ内のインタラクティブな UI を管理します。テンプレートエンジンはサーバー側で HTML を生成して送信するため、クライアントサイドの JavaScript は不要です。

Node.js でのサーバーサイドレンダリング、静的サイト生成、メールテンプレート、シンプルなコンテンツ主体のページにおいては、テンプレートエンジンの方がよりすっきりして軽量な選択肢となることが多いです。

EJS vs Handlebars vs Pug: それぞれの違い

EJS (Embedded JavaScript)

EJS は最も親しみやすい選択肢です。構文は HTML そのままで、値を出力するための <%= %> タグと、ロジックを記述するための <% %> タグを使用します。HTML と JavaScript を知っていれば、すぐに生産性を発揮できます。

<h1>Hello, <%= user.name %></h1>
<% if (user.isAdmin) { %>
  <a href="/admin">Dashboard</a>
<% } %>

EJS は、プロトタイプ、管理ツール、チームがすでに JavaScript に慣れているプロジェクトでの Express ビューエンジンとしてうまく機能します。トレードオフとして、ロジックが増えるとテンプレートが煩雑になりがちです。ビュー内に直接 JavaScript を書きすぎることを防ぐ仕組みがありません。

Handlebars

Handlebars は、ロジックとプレゼンテーションのより厳格な分離を強制します。テンプレートは {{ }} 構文を使用し、基本的な出力以外のことを行うには、登録されたヘルパー関数が必要です。

<h1>Hello, {{user.name}}</h1>
{{#if user.isAdmin}}
  <a href="/admin">Dashboard</a>
{{/if}}

この制約は制限ではなく、機能です。テンプレートを読みやすく保ち、ビジネスロジックを本来あるべき JavaScript の側へ押しやります。Handlebars は、より大きなチーム、メールテンプレート、または開発者以外の人がビューを編集する可能性のあるプロジェクトに適した選択肢です。express-handlebars パッケージは Express とクリーンに統合できます。

Pug テンプレート

Pug は全く異なるアプローチを取ります。HTML 構文を捨て、インデントベースの省略記法を採用しており、閉じタグも山括弧もありません。

h1 Hello #{user.name}
if user.isAdmin
  a(href='/admin') Dashboard

Pug は、構文に慣れれば簡潔で読みやすいテンプレートを生成できます。また、テンプレート継承をネイティブにサポートしているため、大規模なビュー階層にも実用的です。ただし、学習コストは現実にあります。ホワイトスペースエラーのデバッグは煩わしく、構文に不慣れなデザイナーは苦戦するでしょう。

Nunjucks

Mozilla によって開発された Nunjucks は、Jinja2 をモデルにしています。テンプレート継承、マクロ、フィルター、非同期レンダリングをサポートしており、構造化されたサーバーレンダリングのテンプレートやコンテンツ量の多いサイトに対応できる選択肢です。

<h1>Hello, {{ user.name }}</h1>
{% if user.isAdmin %}
  <a href="/admin">Dashboard</a>
{% endif %}

Nunjucks は、EJS よりも構造を必要とするが Pug のインデント形式よりも HTML に近い構文を好む場合の、静的サイト生成やコンテンツ量の多いアプリケーションにおける堅実な選択です。

セキュリティ: 出力のエスケープが重要

これらのエンジンは、通常の出力構文(EJS の <%= %>、Handlebars と Nunjucks の {{ }})を使用すると、デフォルトでエスケープされた出力を提供します。信頼できないユーザーコンテンツに対しては、エスケープされない出力タグ(<%- %>{{{ }}}、Pug の != / !{}、Nunjucks の {{ value | safe }})を絶対に使用しないでください。 生の HTML レンダリングを誤用すると、テンプレートインジェクションや XSS の脆弱性が現実のリスクとなります。

どれを使うべきか?

シナリオ推奨エンジン
簡単なプロトタイプや Express アプリEJS
チームプロジェクト、メールテンプレートHandlebars
簡潔な構文、テンプレート継承Pug
静的サイト、複雑なレイアウトNunjucks

まとめ

テンプレートエンジンは妥協ではありません。フルスタックのフロントエンドフレームワークでは不必要な複雑さが加わってしまうサーバーレンダリングのページ、メール生成、軽量サイトに最適なツールです。チームのワークフローに合った構文のものを選び、テンプレートからロジックを排除し、ユーザーコンテンツを一貫してエスケープしてください。知っておくべきことのほとんどはそれだけです。

FAQ

React や Vue のようなフロントエンドフレームワークと並行してテンプレートエンジンを使用できますか?

はい。多くのアプリケーションは両方のアプローチを組み合わせています。テンプレートエンジンを使用して初期 HTML シェル、マーケティングページ、トランザクションメールをレンダリングし、インタラクティブなダッシュボードや特定のウィジェットには React や Vue を使用するといった具合です。重要なのは、レンダリングコンテキストにツールを合わせることです: 静的または SEO クリティカルなコンテンツにはサーバーサイド HTML を、リッチなクライアントサイドのインタラクティビティにはフレームワークを。

テンプレートエンジンはテンプレートリテラルで手動で HTML をレンダリングするより遅いですか?

ほとんどの場合、パフォーマンスの差は無視できる程度です。EJS、Pug、Handlebars のような最新のエンジンは、テンプレートを JavaScript 関数にプリコンパイルするため、レンダリングは高速でキャッシュされます。手動のテンプレートリテラルは、些細な出力ではわずかに高速かもしれませんが、partial、継承、自動エスケープなどの機能を失います。保守性の向上は、通常、わずかなパフォーマンスコストを上回ります。

ユーザー生成コンテンツを扱うのに最も安全なテンプレートエンジンはどれですか?

ここで取り上げた 4 つのエンジンはすべて、デフォルトで出力をエスケープするため、正しく使用すれば等しく安全です。リスクは、Handlebars のトリプルブレース構文や EJS のダッシュ付き構文のようなタグを使用して、開発者が明示的に生の出力を選択することから生じます。信頼できない入力は敵対的なものとして扱い、ソースでサニタイズし、絶対に必要な場合を除き生のレンダリングは避けてください。

これらのテンプレートエンジンは非同期データやコンポーネントのような最新の機能をサポートしていますか?

Nunjucks は非同期レンダリングをネイティブにサポートしており、レンダリング中にテンプレートがデータを取得する必要がある場合に便利です。Handlebars と EJS は同期レンダリングに焦点を当てていますが、レンダリング前の非同期データ取得と組み合わせることができます。React のような真のコンポーネントモデルを提供するものはありませんが、partial、include、マクロにより、ほとんどのサーバーレンダリングのユースケースに適した再利用可能な構成要素が提供されます。

DevTools for the frontend

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.