ネイティブJavaScriptテンプレート(nJSt)。 JavaScriptネイティブテンプレートエンジン

読者の皆さん、ご挨拶。 ネイティブJavaScriptに基づいてテンプレートエンジンを作成するというアイデアを追いかけて、私は何かに気付きました。 このタスクを実装するNode.JSには、私が望むすべてのものがあり、同じネイティブツールでタスクを完了することが判明しました。 たとえば、VMモジュールは、外部環境から分離されたJavaScriptコードを実行するためのメインツールでした。 テンプレートの挿入は純粋なJSですが、 メス、 require、globalなど、あらゆる種類の危険なツールはそこに到達しません。



フライトの詳細なデブリーフィングに進む前に、すぐに使用例を見てみましょう。これは、他の何よりも本質をより明確に反映する可能性が高いでしょう。 サーバー作成コードは提供しません。テンプレート自体を説明し、特定のコンテキストで解析します。



HTMLテンプレート:

<html >

<head >

<title > #{PageTitle} </title >

</head >



<body >

<h1 > #{PageTitle} </h1 >



<ul >

<# for (var i=0; i
<List .length; i++) { # >

<li >

<#

if (typeof List[i] !== 'object') {

show(List[i]);

} else {

show(List[i].name +' - '+ List[i].note);

}

#>

</li >

<# } #>

</ul >

</body >

</html >




FractalizeR's HabraSyntax Source Code Highlighter .







コンテキスト:

var context = {

PageTitle
: ' jJSt test ' ,

List
: [ ' First ' , { name : ' Second ' , note : ' 2th ' } , ' Third ' ] ,

} ;

var result = njst . parse ( html , context , { debug : 1 } ) ;




FractalizeR's HabraSyntax Source Code Highlighter .







アイデア



これに至った経緯について少し話すべきだと思います。 ほとんどの人が知っている言語(PHP)を使用して、ネイティブテンプレートに関する1C-Bitrixのアイデアに触発されました(Node.JSでも同じことをすることにしました)。 しかし、私の意見では、このオプションは純粋なJavaScriptであるため、さらに有利です。 タイプセッターは、テンプレート、HTML-CSS-JavaScriptを記述します...さて、ここで彼はプログラミング言語から熟知しているはずのテンプレート挿入をJavaScriptに再び記述します。 また、新しいテンプレートエンジンの複雑な構文を詳しく調べる必要はありません。 さらに、多くのテンプレートエンジンでは、完全に些細なタスクの実装を許可しない落とし穴がポップアップします。 もちろん、理想的には、1つのプロジェクトのフレームワーク内でロジックを修正する必要があります。これは正常ですが、普遍性が必要な場合は、何らかの理由でロジックを取得しません。 もちろん、私はプログラミングスキルをレイアウトデザイナーに示すための手段を提案しません。また、計算はテンプレートにロジックを転送するのではなく、必要最小限の挿入になります。 鞭の方法はそれを徹底的に教えてくれません。ここでは、自己規律に場所があるはずです。 Node.JSに付属のVMモジュールのおかげで、ホイップメソッドについて説明すると、テンプレートにロジックを実装する可能性は大幅に減少します。



このアイデアを実現するための以前の試みでは、次のテンプレート挿入デザインを使用しました。



<script type = " nodejs " > ... </script >



FractalizeR's HabraSyntax Source Code Highlighter .







ほとんどすべてのエディターでJSコードの強調表示が保証されているため、これは良かったです。 さらに、埋め込みコードが同じJavaScriptであることを思い出させます。 しかし、この手法の短所の冷静なリストを作成したとき、私はすぐにこれから逃げました:



必要なものがわかっていたので、投げることはあまりありませんでした。 まず、特別なコードなしで特定のフィールドを出力するための短くコンパクトなバージョンも提供します。 次に、解析の競合を避けるために、JS構文にない文字を使用します。 最初は、テンプレートエンジンの一般的なオプションである<% ... %>



を使いたいと思っていました。 私のメモ帳++はそれを強調し、テンプレートコードがすぐに見えることは良いことであることに注意しました。 しかし、HTML挿入のために、私はもともと次の構造を使用しました:



<% if (true) { &> html <& } %>



FractalizeR's HabraSyntax Source Code Highlighter .







つまり、純粋なHTMLを出力するために、 %>



および<%



ではなく、 &>



および<&



。 そして、このバックライトはすぐに問題になりました。 ラティス<# if (true) { &> html <& } #>



のオプションを選択しました。 そしてしばらくして、解析の原理を変更し、 <&>



トラブルを解消しました。 そして最終的に、すべてが同様のPHP挿入に似るようになりました(ところで、テンプレートエンジンはコード挿入の原則に近づいています)。 しかし、どういうわけか格子をパーセント記号(<% if (true) { %> html <% } %>)



変更しませんでした。 他に、もしそれが無駄だと思ったら-それについて教えてください。



使用可能な挿入物は次のとおりです。



仕様書



次に、使用に関する推奨事項について説明します。 ここには特別な制限がないので、govnokodingの可能性は自分にとって素晴らしいので、トーンを設定する必要があります。



まず: #{...}



-特定の値、または以前の変数の名前を得るために、コンテキストからキーの名前のみを書き込むことをお勧めします。それらの一部が可能であっても、不要な操作はありません。 たとえば、配列を文字列にアセンブルするには、次のようにします。 #{arr.join(', ')}



-それは大きな罪にはならないと思います。 改行と;



ここは意図的に無視されます。 あらゆる種類のコード(ループ、条件など)には、 <# ... #>



使用します。



insert <# ... #>



内の出力が必要な場合は、 show()



関数またはtoShow



変数が入力されます(ただし、置き換えられません。そうでない場合は、from show()



を含む以前の出力が上書きされます) ) これらのツールを使用した出力例を次に示します。

<#

while (toShow.length < 100) {

show('I like it! ');

toShow += 'I love it! ';

}

#>




FractalizeR's HabraSyntax Source Code Highlighter .







第二に:理論上単純なルールですが、実際には彼らはしばしばそれを忘れます:余分なコーディングはありません! 結論に必要なのは、サイクルと条件で十分だと思います。 関数は作成できますが、これは致命的な罪であることを常に忘れないでください。そうすると、指が萎縮し、テンプレートに関数を書くことができなくなります。



3番目: JavaScriptの仕様に慣れていない場合は(非公式ではありますが)、必ずそれから始めてください 。 他の人があなたのコードで作業する可能性がある場合、またはしばらくしてからあなた自身が後で自分自身を理解することを望んでいる場合は、それを使用する予定です。 これは非常に一般的な問題であり、私自身も病気でしたが、被害者の役割を担った後、この瞬間がどれほど重要かを認識しました。 時には、脳が何らかの方法で解釈できず、著者自身が向精神薬なしではほとんど対処できないようなものに出くわします。



範囲



頭の中で点滅する可能性が最も高い質問の1つは、「変数var v = true;



を設定した場合ですvar v = true;



次のテンプレート挿入で表示されますか?」-答えはYESです。 「仕組み」を理解するのが難しい場合は、PHPを知っているとよいでしょう。nJStテンプレートの挿入はPHPの挿入であると想像してください。動作はこのタイプに最も似ています。 結論と同様に:

#{...} = <?=...?>

<# ... #> = <? ... ?>




FractalizeR's HabraSyntax Source Code Highlighter .







安全性



上記のように、コンテキストのみがテンプレートに取得されます。 グローバルオブジェクトはありません(必須、グローバル)。 外部グローバル変数の上書きも失敗します。 一般に、すべてはコンテキスト内にあります。 もちろん、外観を操作する必要がある場合は、要求に応じてこれを実行するコンテキストで目的の機能を転送します。



私は非表示にしません、まだギャップがありますが、次のバージョンではそれらのカバーを扱います。 たとえば、 <# while(true)++ #>



と記述すると、プロセッサの負荷が100%になり、ノードプロセスでkillを呼び出すまで、コンピューターをヒーターとして使用でき、ノードでのさらなるアクションは不可能になります。 次のバージョンでは、このようなサーバーのフリーズを回避するために、タイマーをハングさせ、遅延した場合は実行を停止します。



機能とアプリケーション



可能性は、あなたの想像力によってのみ制限されます。なぜなら、私たちは私たちが望むものを文脈に伝えるからです。 GitHubの例では、現在のページをダウンロードする関数を呼び出すデモがあります。 ダウンロード関数はコンテキストに渡され、テンプレートで呼び出されます。 プロジェクトのツールであり、おそらく外部環境で動作するコンテキストで、任意の機能を転送できます。 一般に、JSを知っていれば、問題はないはずです。 わからない場合は、1つと2つです。



将来のバージョン





健康のために使用



さらに多くのサンプルと詳細が必要な場合は、GitHubのサンプルフォルダーを参照し、モジュール自体をダウンロードして、ソースコードを調べてください。



GitHubの nJSthttps : //github.com/unclechu/njst



フィードバックと修正提案を待っています。



All Articles