H 튜토리얼 초안에 간단한 js 템플릿 엔진을 작성합니다. H 초안에서 간단한 js 템플릿 엔진을 작성합니다. 실행 가능한 코드 생성





이제 js 애플리케이션의 템플릿에 대한 두 가지 옵션만 표시됩니다. 프레임워크에 내장된 템플릿 엔진과 jquery 누들(후자가 가장 일반적임)입니다. 이는 많은 사람들이 템플릿 엔진이 작동하는 방식을 이해하지 못하기 때문이라고 생각합니다. all (나는 기능이 아니라 내부에 대해 이야기하고 있습니다) .
이 기사에서는 정규식을 기반으로 간단하지만 강력한 템플릿 엔진을 만드는 방법을 보여 드리겠습니다.

그러나 주제에 포함되지 않은 사람들을 위해 그것이 무엇인지, 그리고 그것이 우리에게 무엇을 줄 것인지에 대해 조금 설명합니다.

웹상의 템플릿 엔진은 HTML 템플릿을 사용하여 최종 HTML 페이지를 생성할 수 있게 해주는 소프트웨어입니다. 템플릿 엔진을 사용하는 주요 목적은 실행 가능한 코드에서 데이터 표시를 분리하는 것입니다. 종종 이는 프로그래머와 레이아웃 디자이너의 병렬 작업 가능성을 보장하는 데 필요합니다. 템플릿 엔진을 사용하면 한 사람이 전체 프로젝트를 수행할 때 코드 가독성이 향상되고 모양 변경이 향상되는 경우가 많습니다.

그래서 우리는 템플릿을 1패스로 렌더링하고 로직과 별도의 뷰를 갖고 싶습니다. 일반적으로 템플릿 엔진은 비슷한 인터페이스를 가지고 있습니다.
template.Run("템플릿 URL", ( VarName:"VarValue" ));
아래는 자세한 설명이 포함된 코드입니다(무엇과 이유).
window.template = ( //TemplateGet 보기 로드: function (TemplateUrl) ( // 1. 새 XMLHttpRequest 객체 생성 var xhr = new XMLHttpRequest(); // 2. 구성: "TemplateUrl" URL에 대한 GET 요청 xhr .open ("GET", TemplateUrl, false); // 3. 요청 보내기 xhr.send(); if (xhr.status >= 200 && xhr.status< 400) { // вернуть результат return xhr.responseText; } else { // обработать ошибку alert(xhr.status + ": " + xhr.statusText); // пример вывода: 404: Not Found return ""; } }, //класс функций для рендинга Render:{ //а в этом классе мы напишем все функции рендера func:{ //рендит переменные vars: function(html, vars){ //ищем все переменные в шаблоне var $ = html.match(/{{var.(.*?)}}/g); //проверяем нашли ли что то if (Array.isArray($)) { //мы нашли переменные в шаблоне. Необходимо их все распарсить. $.forEach(function (item) { //item содержит найденую строку {{var.VarName}} //по этому мы должны распарсить ету строку дабы получить только VarName item = item.replace("{{var.", ""); item = item.replace("}}", ""); //у нас есть имя переменной. Пора проверить передали ли мы такую //и обработать ошибки if (vars === undefined){ //перенную не передали. //пишем об ошибке в консоль и заменяем её значение в шаблоне на null console.warn("Переменная "+item+" не найдена"); html = html.replace("{{var." + item + "}}", "null"); } else { //переменную мы нашли. Вставим ка её в шаблон html = html.replace("{{var." + item + "}}", vars); } }); } //удалим обьект с переменными delete vars; //вернём html return html; } }, //точка входа в рендер. Run:function(html, vars){ html = this.func.vars(html, vars); return html; } }, //точка входа Run: function (TemplateUrl, vars) { //загружаем шаблон var html = this.TemplateGet(TemplateUrl); //отправляем шаблон рендеру html = this.Render.Run(html, vars); //удаляем обьект с переменными. Он нам больше не нужен, а может занимать много места delete vars; //результат шаблонизатор вставит в document.getElementById("page").innerHTML = html; } }; //вызовем представление template.Run("test.tpl", { VarName: "test" });
그리고 test.tpl에서 그냥 쓰세요.
((var.VarName))

이제 jquery 국수가 줄어들기를 바랍니다)

NodeJS 또는 Rhino와 같은 JavaScript 환경을 사용하는 경우 클라이언트와 서버에서 콘텐츠를 렌더링해야 하는 경우를 포함하여 JavaScript 템플릿 엔진이 필요할 수 있는 몇 가지 경우가 있습니다. 나는 단순한 것부터 이국적인 것까지 사용 가능한 많은 템플릿 엔진을 고려했다고 즉시 말해야합니다. 무엇보다도 저는 단순한 것에 관심이 있었지만 템플릿에서 복잡한 로직을 사용할 수 있도록 허용했는데 EJS가 그 중 하나였습니다. 그러나 이것은 내가 원하는 것과 다소 다르게 작성되었으며 한편으로는 불필요한 것이 많았고 다른 한편으로는 주요 기능이 너무 복잡했습니다. 나는 그의 템플릿을 훨씬 쉽게 컴파일하고 렌더링할 수 있는 기회를 보았습니다.

EJS의 적용

템플릿 엔진이 하는 일은 템플릿과 데이터를 가져와서 반환하는 것입니다. 콘텐츠 인스턴스가공하여 얻은 주형이 구체적인 내용을 바탕으로 데이터 인스턴스.

EJS의 경우 아이디어는 간단합니다. 템플릿의 일부로 HTML이 PHP 스크립트 파일의 코드와 결합되는 방식과 유사하게 렌더링된 콘텐츠를 인라인 JavaScript의 비트와 결합할 수 있습니다. 코드에서는 전역 변수와 호출 시 렌더러에 전달하는 변수가 모두 표시됩니다. 또한 링크 태그나 그림과 같이 자주 사용되는 구조의 형성을 단순화하는 소위 도우미 기능도 볼 수 있습니다.

코드는 태그 또는 태그로 구성됩니다.

다음과 같이 보일 수 있습니다.

나는 공간의 존재가 중요하지 않다는 것을 보여주기 위해 의도적으로 다양한 스타일의 구성을 작성했습니다. 템플릿을 사용하여 출력을 생성할 때 템플릿 내부의 코드가 작동하는 변수 역할을 하는 속성이 있는 객체를 전달합니다. 요점은 JavaScript 자체의 논리적 구조를 사용하여 결과 콘텐츠의 모양을 유연하게 변경할 수 있다는 것입니다. 또는 템플릿이 DOM 트리에 포함된 후 렌더링되어야 하는 경우 [% %] 태그를 사용할 수 있습니다. 내 사용 패턴에 비추어 볼 때 그다지 유용하다고 생각하지 않았습니다.

EJS 개선

원본 템플릿 엔진에서는 파일에서 템플릿을 로드하는 추가 기능이 만족스럽지 않았습니다. 이 기능은 클라이언트 측뿐만 아니라 서버 환경에서도 사용되어야 했기 때문에 원칙적으로 필요하지 않았습니다. 나는 또한 코드 로직의 복잡성에 대해 기본 호출을 사용하는 것을 선호하기 때문에 컴파일러 자체의 복잡성에 불쾌하게 놀랐습니다. 이러한 이유로 나는 나중에 이야기할 컴파일러를 처음부터 작성하기로 결정했습니다.

소스 템플릿 구문 분석

편집은 항상 미리 정해진 규칙에 따라 원본 자료를 실제로 분석하는 것부터 시작됩니다. 우리의 규칙 세트는 특수 태그의 콘텐츠와 다른 모든 콘텐츠를 구별하는 것으로 요약됩니다. 사용자 정의 태그의 구조를 살펴보면 간단한 정규식을 사용하여 태그 전체를 쉽게 캡처할 수 있습니다. 내부 코드로 무엇을 해야 할지 이해하려면 실제 코드 외에도 여는 태그를 꺼내야 한다는 점을 기억하세요. RegExp는 다음과 같습니다.

/(?:\n\s*)?(])+)%>/gm

그래서 우리는 여기서 무엇을 하고 있나요?

  • (?:\n\s*)? - 코드 태그에 줄바꿈과 모든 공백이 있으면 제거합니다. 물론 이 작업을 전혀 수행할 필요는 없었지만, 우리는 마취자이므로 생성된 콘텐츠에 빈 줄이 많이 나타나는 것을 방지하겠습니다. 하위 패턴의 시작 부분에 있는 지정자 ?:는 해당 내용이 캡처되지 않고 단순히 건너뛴다는 의미입니다.
  • (] - 코드는 % 가 아닌 모든 문자이거나 뒤에 > 문자가 오지 않는 % 문자입니다.
  • (?:[^%]|[%][^>])+는 우리의 코드입니다. 이러한 시퀀스는 두 번 이상 나타날 수 있지만 캡처해서는 안 됩니다.
  • ((?:[^%]|[%][^>])+) - 코드 - 전체 시퀀스를 전체적으로 캡처합니다.
  • %> - 닫는 태그는 캡처되지 않습니다.
  • gm - 전역 전체 텍스트(여러 줄) 처리를 활성화합니다.

보시다시피 모든 것이 매우 간단하므로 이 정규식으로 무엇을 해야 할지 알아내는 것이 남아 있습니다. 여기서는 지정된 구분 기호를 사용하여 문자열을 분할하고 결과 하위 문자열의 배열을 반환하는 매우 유용한 String.split 메서드가 유용하게 사용됩니다. 이 방법의 특징은 정규식을 구분 기호로 사용할 수 있으며, 캡처된 하위 패턴이 있는 경우 이에 해당하는 하위 문자열도 일반적인 순서로 결과 배열에 포함된다는 것입니다. 이는 템플릿 컴파일러의 기본 최적화에 대한 아이디어를 제공합니다. 문자열을 정규식으로 분할하고 일련의 인라인 콘텐츠 조각과 코드 지정자 뒤에 이 코드 조각을 얻은 다음 처리하는 것만으로도 충분합니다. 결과 배열.

실행 가능한 코드 생성

이제 우리는 구문 분석된 템플릿을 갖게 되었습니다. 이는 이를 실행 가능한 JavaScript 코드로 상당히 선형적으로 변환하는 방법을 이미 상상할 수 있음을 의미합니다. 우리에게 필요한 것은 함수를 얻는 것뿐입니다. 이를 호출하면 원본 템플릿에 따라 콘텐츠가 올바르게 구성됩니다. 따라서 템플릿의 내용 일부를 그대로 삽입하고, 해당 값을 변수 위치에 삽입한 후 코드를 실행해야 합니다.

다음과 같은 간단한 방법으로 정리해보자:

  • eval을 호출하기에 적합한 문자열로 함수를 구성하겠습니다.
  • 함수 본문에서 콘텐츠 조각을 특정 결과 변수에 순차적으로 첨부하도록 구성합니다.
  • 일반적인 JS 코드를 그대로 붙여 넣습니다.

그러나 우리는 다음과 같은 문제를 해결해야 합니다.

  • 실행 가능한 템플릿 함수의 본문에 변수 및 도우미 함수 전달
  • 템플릿에 사용된 변수와 겹치지 않도록 결과 변수 구성
첫 번째 문제에 대한 해결책

첫 번째 문제를 해결하는 가장 쉬운 방법은 with 구문을 사용하는 것입니다. 예, 이것이 바로 개발자 간의 열띤 토론의 영원한 주제이자 w3c 표준화자의 골치 아픈 문제입니다. 이는 바로 JSLINT와 같은 유효성 검사기 및 Closure Compiler와 같은 컴파일러가 그토록 싫어하는 것입니다. 이 구성이 하는 일은 객체를 지역 변수의 가시성 수준으로 제공하는 것으로 생각하는 가장 간단한 방법입니다. 즉, 마치 일반 변수인 것처럼 이름으로 객체의 속성에 액세스할 수 있습니다. 즉 객체 이름 앞에 점을 붙이지 않고, 다음과 같습니다.

Var obj = ( foo: "foo입니다.", bar: 42 ); with(obj)( foo += " 그리고 bar 는 " + bar; )

값을 읽을 때 모든 것이 매우 간단하고, 작성할 때, 특히 구문과 함께 중첩된 것을 사용할 때 그렇게 사소하지 않습니다. 그러나 템플릿에서는 주로 값을 읽어야 하므로 다른 버팀목을 만드는 대신 기본 접근 방식을 사용하는 것이 정당화되는 것 이상입니다. 정확하게 말하면 로컬 변수의 두 가지 상호 중첩된 가시성 수준이 실제로 생성됩니다. 하나는 객체에서, 다른 하나는 with 본문 내부에서 생성됩니다. 즉, 로컬 변수를 생성할 때 원래 객체에 들어 가지 않습니다.

두 번째 문제에 대한 해결책

템플릿 렌더링 기능에서 콘텐츠 조각을 어떻게 수집할지 파악하는 것이 남아 있습니다. 가장 먼저 떠오르는 것은 함수 본문에 좀처럼 보이지 않는 이름으로 지역 변수를 생성하고 실행될 때 필요한 모든 것을 여기에 첨부하는 것입니다. 솔직히 처음에는 그렇게 하고 싶었습니다. 변수 이름을 교차할 확률을 최소한으로 줄이면 매우 좋은 아이디어입니다. 그러나 확실히 이 솔루션은 미학적으로 그다지 만족스럽지 않습니다. 고급 예술의 창작자로서 우리는 이 완벽한 기능에서 지역 변수를 전혀 생성할 권리가 없습니다.

우리가 무엇을 가지고 있는지 살펴보겠습니다. 그러나 일반적으로 옵션이 많지 않습니다. 언어의 특성으로 인해 사용자가 어쨌든 템플릿에서 사용해서는 안 되는 this 개체 또는 인수 개체를 사용하고, 가능하다면 특별한 방법으로만요. 모든 장단점을 고려한 후, 함수에 전달되는 이름 없는 인수 배열인 인수를 그 중 하나에 사용하기로 결정했으며 콘텐츠를 올바르게 구성하는 데 필요한 모든 것을 넣을 것입니다.

구현 기능

이제 우리는 완전한 템플릿 엔진을 구현하기 위한 모든 것을 갖추었습니다. 앞서 말했듯이 원본 EJS와 완전히 호환되지는 않지만 이를 위해 생성된 템플릿을 사용할 수 있습니다. 또한 자동 템플릿 로더가 구현되지 않으므로 이 특정 실행 환경에서 사용하는 프레임워크의 원칙에 따라 직접 연결해야 합니다.

이제 코드로 직접 이동할 시간입니다. 기본 개체, 즉 템플릿 개체부터 시작하여 모든 부분을 부분적으로 살펴보겠습니다.

// 생성자 var EJS = function(src)( if(typeof src == "string")( // 템플릿이 전달된 경우 this.compile(src); // 즉시 컴파일 ) ); // 프로토타입 EJS.prototype = ( regexp: /(?:\n\s*)?(])+)%>/gm, helper: () // 도우미 함수 );

EJS.prototype.compile = function(src)( delete this.method; delete this.error; // 이전 컴파일러 호출 추적 삭제 var p = src.split(this.regexp), // 결과 분석 r = , // 결과 어셈블리 i, o; this.parsed = p; // 파싱 결과 즉시 저장 // 콘텐츠 생성 함수 빌드 for(i = 0; i< p.length; i++){ if(p[i] == " 0) { str += parts[ len ]; } } return str; }

위 코드는 최종 결과보다 약간 작습니다.
그래서 예를 들어 현재 요소가 점으로 주어지면 어떻게 해야 하는지 보여주지 않았습니다.
또한 필터 처리도 제공하지 않았습니다.
게다가 최종 버전에서는 "현재 요소"나 "대상 값"이 함수인 상황의 처리에 "스스로"를 추가했습니다.

하지만 제 목표는 컨셉 자체를 보여드리는 것이었습니다...

그리고 이미 기사 시작 부분에서 언급했듯이 결과를 찾을 수 있습니다.
최종 예.

누군가에게 유용하길 바랍니다.
관심을 가져주셔서 감사합니다!

이 기사 - 프런트엔드 개발을 위한 템플릿 엔진 개요. JS로 작업하는 경우 템플릿 엔진은 더 깔끔한 기본 코드를 작성하고 애플리케이션 작업을 더 쉽게 만들어 주기 때문에 훌륭하고 적절한 선택입니다. Wikipedia가 제공하는 가장 인기 있는 JS 템플릿 엔진을 고려해 보세요. 이러한 템플릿 엔진을 사용하여 효율적으로 작업하려면 언어에 대한 충분한 이해와 이 영역에 대한 충분한 기술이 필요합니다.

ICanHaz.js는 Mustache 템플릿을 사용하는 매우 간단하고 가벼운 라이브러리입니다. 이를 사용하면 type=”text/html”을 사용하여 스크립트 태그에 템플릿 조각을 정의하고 유효성 검사를 통해 ID를 통해 호출할 수 있습니다.

Mustache.js는 이 분야에서 매우 인기 있는 템플릿 엔진입니다. 서버 및 클라이언트 측 솔루션을 제공하므로 여러 템플릿 엔진 사용에 대해 걱정할 필요가 없습니다. 훌륭하고 명확한 문서와 대규모 커뮤니티가 있습니다. 템플릿에서 JSON 형식의 데이터를 사용합니다. 널리 사용되는 프로그래밍 언어에서 훌륭하게 실행됩니다. 최신 버전의 라이브러리는 공식 페이지에서 다운로드할 수 있습니다.

Mustache의 확장이며 완벽하게 호환됩니다. 불필요한 로직으로 인해 과부하가 발생하지 않아 실행 속도가 빠릅니다. HTML은 JSON 형식의 데이터에서 동일한 방식으로 생성됩니다. 중요한 단점은 라이브러리의 무게가 크다는 것입니다.

Underscore.js는 jQuery 작업을 위한 편리하고 실용적인 도구입니다. 60개 이상의 기능 유틸리티가 있습니다. 이 템플릿 엔진은 배열, 함수, 객체, 컬렉션 등으로 작업할 때 jQuery의 기능을 향상시킵니다. jQuery UI의 5가지 대안

Hogan.js는 Twitter에서 개발한 템플릿 엔진입니다. 웹 브라우저의 빠른 동적 처리를 위한 중간 템플릿 빌더로 사용됩니다. Mustache는 이 템플릿 엔진 개발의 기반이 되었지만 Hogan.js가 훨씬 빠릅니다. 파서 기능에 액세스하기 위한 API가 제공됩니다. 템플릿 스캐닝과 파싱은 별도의 방법으로 수행되므로 템플릿을 서버에서 전처리하고 클라이언트 측에서 Javascript 형식으로 사용할 수 있습니다.

- 서버 템플릿 작업에 사용되지만 일반적으로 다른 목적에도 적용 가능합니다. 코드 가독성이 높고 보안성이 좋습니다. 이는 클라이언트 부분에서 작동하며 유틸리티를 사용하여 명령줄에서 HTML 템플릿을 컴파일하는 것이 가능합니다. 템플릿 엔진의 이름이 Pug.js로 바뀌었지만 이전 이름을 사용하면 개발자를 위한 많은 문서와 유용한 정보를 찾을 수 있습니다.

ECT 템플릿 엔진은 속도를 위해 설계되었습니다. Coffeescript 템플릿 엔진을 기반으로 합니다. Node.js와의 호환성이 좋고 구문이 매우 간단합니다. 또한 이 라이브러리의 성능을 보여주는 예비 테스트도 볼 수 있습니다.

Hyper Host™는 귀하가 JS 세계에서 즐겁게 일하기를 바라며 귀하의 멋진 프로젝트를 당사 사이트에 올릴 준비가 되어 있습니다!

4366회 오늘 3회 조회됨