【ESLint】eslint-plugin-lodash-templateがEJSを(部分的に)サポートしたよ


かなり前に、【ESLint】eslint-plugin-lodash-template作ってみたよ という記事を書き、ちょっと前に 【ESLint】eslint-plugin-lodash-templateがJavaScriptテンプレートをサポートしたよ という記事を書きましたが、eslint-plugin-lodash-templateをJavaScriptテンプレートサポートさせたときついでに、部分的にEJSをサポートをしたのでその思い出を残します。

eslint-plugin-lodash-templateを基本的な使い方で使えば、EJSESLintが動くはずなので、
EJSでの使い方の説明は無いです。仕組みをどう変えたかの思い出の話がメインです。

eslint-plugin-lodash-templateとは

Lodashの_.templateに渡して使えるテンプレートタグ内のJavaScriptに対してESLintで検証できるようにするESLintのプラグインです。

今回の変更でEJS構文でもESLintでエラー検出ができるようになりました!

WEBで試す

EJSとは

JavaScriptを使ったテンプレート構文です。

<% if (user) { %>
  <h2><%= user.name %></h2>
<% } %>

公式はこちら https://ejs.co/

Lodashの_.templateに似た構文ですが、
HTMLエスケープする(EJS<%=)、しない(EJS<%-)、の意味が逆だったり、
<%_ ... _%>のような無駄な空白を除去するタグ記法があったり、
<%# ... %>というコメントタグ記法があったり、
<%%というリテラルを表現する記法があったりします。

EJSを部分的にサポートしました

以前から、受け入れるタグ構文をカスタマイズする機能(parserOptionsを利用)がありましたが、
これを拡張してEJSの記法を設定できるようにしました。
(拡張子.ejsに自動的に適用する共有設定も提供するようにしました。)

EJSのタグを処理できるように変更しました。

EJSはタグ記法はLodashの_.templateに比べてタグの記法が豊富です。
開始タグ・終了タグに様々な種類があり、組み合わせることができます。
以前までは、開始タグ・終了タグを1種類ずつしか受け入れられなかったのですが、
EJSをサポートするために、開始タグ・終了タグの種類を配列で受け入れ、構文解析できるようにしました。

// script部分
evaluate:    [ ["<%", "<%_"] /*開始タグ2種類*/, ["%>", "-%>", "_%>"] /*終了タグ3種類*/ ],
// 補完部分(HTMLエスケープなし)
interpolate: [  "<%-"        /*開始タグ*/    , ["%>", "-%>", "_%>"] /*終了タグ3種類*/ ],
// 補完部分(HTMLエスケープあり)
escape:      [  "<%="        /*開始タグ*/    , ["%>", "-%>", "_%>"] /*終了タグ3種類*/ ],

また、以前までは、コメントやリテラルを処理する機能はなかったのですが、(Lodashの_.templateにはコメントやリテラルという概念はなかったので。)
コメントタグ記法、リテラルタグ記法も受け入れ、構文解析できるようにしました。

// コメント部分
comment:    [ "<%#" /*開始タグ*/, ["%>", "-%>", "_%>"] /*終了タグ3種類*/ ],
// リテラル
literal:    [ "<%%" /*タグ (リテラルには終了タグの概念はない様子)*/ ],

共有設定で.ejs用の設定を適用

eslint-plugin-lodash-templateの提供する共有設定で、以下ようにoverridesを利用して、拡張子.ejsのファイルにEJSで動作する用のparserOptionsを設定しています。
これによって.ejsのファイルでは自動的にEJSのタグで構文解析するようになりました。

module.exports = {
    // ...
    overrides: [
        {
            files: ["*.ejs"], // `.ejs`に適用
            parserOptions: {
                // eslint-plugin-lodash-template用の設定
                templateSettings: {
                    // 上記で書いたやつ
                    evaluate: [["<%", "<%_"], ["%>", "-%>", "_%>"]],
                    interpolate: ["<%-", ["%>", "-%>", "_%>"]],
                    escape: ["<%=", ["%>", "-%>", "_%>"]],
                    comment: ["<%#", ["%>", "-%>", "_%>"]],
                    literal: ["<%%"],
                },
            },
        },
    ],
}

結果

これらの変更でEJS構文でもESLintでエラー検出ができるようになりました!(再掲)

なぜ(部分的)と言っているのか?

EJSには古い構文で<% include _header %>というようなincludeディレクティブというのがまだ息してるらしく、eslint-plugin-lodash-templateはこれを解析できません。なので(部分的)サポートということにしています。