この記事は私のブログに掲載しているThe Use of JSX as a Template Engineの内容の日本語版です。
はじめに
JSXは素晴らしい技術です。JSXはReact、Preact、Solidなど様々なUIライブラリにてJavaScriptでUIを表現するのに使用されています。さらに、JSXは馴染みのJavaScriptの構文とTypeScriptによる静的型付けによって、快適な開発体験をもたらしてくれます。最近、JSXをクライアントサイドのインタラクティビティを使用しない、テンプレートエンジンとしての利用ケースを目にするようになりましたが、長所と短所があります。
JSXをテンプレートエンジンとして使用する場合
JSXのツリーをHTML文字列に変換することによって、テンプレートエンジンとして使用することが可能です。
import { renderToString } from "react-dom/server";
const html = renderToString(<App />);
// => <html lang="en"><head><meta charSet="UTF-8"><title>Document</title></head><body>...
長所
JSXはJavaScriptの拡張構文なので、TypeScriptによる型チェックや自動補完機能がIDEやエディタから受けることができます。JavaScriptに慣れている人なら、ループや条件分岐など新しく構文を学ぶ必要がありません。
短所
空白やインデントが保持されないケースがあります。またHTMLコメントやSSIディレクティブの記述を通常のHTMLのように記述することができません。それを行おうとすると、ReactならdangerouslySetInnerHTMLpropを利用する必要があり、不必要な<div>を記述することがあり、直感的ではありません。
通常のHTML
<!-- HTML comments -->
<!--#include virtual="/included.shtml"-->
JSX
<main>
<div
dangerouslySetInnerHTML={{
__html: `
<!-- HTML comments -->
<!--#include virtual="/included.shtml"-->
`,
}}
/>
</main>
SSX
SSXというサーバーサイドのみでの利用を目的としたJSXのライブラリがあります。SSXではJSXに追加の<div>は不要で生のHTMLコードを挿入することができます。
<main>
{{ __html: "<!-- HTML comments -->" }}
{{ __html: '<!--#include virtual="/included.shtml"-->' }}
</main>
テンプレートエンジンはどうか?
EJS、Handlebars、Nunjucksなど様々なテンプレートエンジンが存在し、各々が提供しているタグやディレクティブによって動的にHTMLを出力することができます。
(例)Handlebarsの場合
{{#if condition}}
<p>{{message}}</p>
{{/if}}
<ul>
{{#each items}}
<li>{{this}}</li>
{{/each}}
</ul>
長所
テンプレートエンジンはHTML文字列をそのまま出力することができます。つまり、空白・インデント・HTMLコメント・SSIディレクティブを完全に保持することができます。また、テンプレートエンジンは空白の挙動を制御する機能が備わっている場合が多いです。
短所
JSXと比較すると、静的型チェックを受けられないです。そのため、不正なHTMLを記述した場合にエラーを発生させることができません。
結論
JSXをテンプレートエンジンとして利用することはたくさんのメリットがあります。しかし、インデントや空白のルールを持つHTMLのスタイルガイドに準拠する必要がる場合は、私はテンプレートエンジンを選択します。