37
자바스크립트 템플릿 엔진 ABC Talk / Steve Ahn

JavaSript Template Engine

Embed Size (px)

DESCRIPTION

at ABC Talk

Citation preview

자바스크립트����������� ������������������  템플릿����������� ������������������  엔진

ABC����������� ������������������  Talk����������� ������������������  /����������� ������������������  Steve����������� ������������������  Ahn

오늘은.

-����������� ������������������  간단하게����������� ������������������  템플릿����������� ������������������  코드를����������� ������������������  만들어보면서,

-����������� ������������������  자바스크립트����������� ������������������  템플릿����������� ������������������  처리����������� ������������������  과정의����������� ������������������  큰����������� ������������������  그림을����������� ������������������  이해하고,

-����������� ������������������  상황에����������� ������������������  맞게,����������� ������������������  어떤����������� ������������������  템플릿����������� ������������������  엔진을����������� ������������������  선택할����������� ������������������  지,

����������� ������������������  ����������� ������������������  ����������� ������������������  또는����������� ������������������  어떻게����������� ������������������  만들지에����������� ������������������  대해����������� ������������������  가이드하는����������� ������������������  게����������� ������������������  목표!

-����������� ������������������  각����������� ������������������  템플릿����������� ������������������  엔진의����������� ������������������  문법이나����������� ������������������  사용법은����������� ������������������  제외!

우리가����������� ������������������  하려는����������� ������������������  것.

-����������� ������������������  HTML����������� ������������������  조각을����������� ������������������  동적으로����������� ������������������  만들어서����������� ������������������  페이지에����������� ������������������  추가!

-����������� ������������������  Ajax로����������� ������������������  요청해서����������� ������������������  데이터를����������� ������������������  가져오고,

-����������� ������������������  JSON����������� ������������������  형태로����������� ������������������  데이터를����������� ������������������  받아서����������� ������������������  생성한다.

-����������� ������������������  그리고,����������� ������������������  최대한����������� ������������������  관리하기����������� ������������������  편하고����������� ������������������  빠르게~!

그럼����������� ������������������  템플릿����������� ������������������  엔진은?

문자열����������� ������������������  치환!

����������� ������������������  ����������� ������������������  <div>[����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ]가����������� ������������������  [����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ]할����������� ������������������  때����������� ������������������  뽀뽀뽀~</div>

����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  who����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  when

특정����������� ������������������  형식을����������� ������������������  가진����������� ������������������  문자열을����������� ������������������  여러����������� ������������������  데이터로����������� ������������������  출력한다.

만들어보자.

// 어떤 서버에서 데이터를 받아왔다고 가정하면,requestAjax(function (data) { // data = { who: ‘택배’, when: ‘도착’ }; // 데이터를 받아서 HTML 코드를 생성한 후에

// DOM에 추가하면 땡!

});

일단은����������� ������������������  간단하게!

// 어떤 서버에서 데이터를 받아왔다고 가정하면,requestAjax(function (data) { // data = { who: ‘택배’, when: ‘도착’ }; // 데이터를 받아서 HTML 코드를 생성한 후에 var result = getPpopo(data);

// DOM에 추가하면 땡! $(‘#result’).html(result);

});

function getPpopo(data) { return data.who + ‘가 ‘ + data.when + ‘할 때 뽀뽀뽀~’;}

템플릿����������� ������������������  종류가����������� ������������������  다양해진다면?

function getPpopo() { ... }function getFoo() { ... }function getBar() { ... }

...

function getBaz() { ... }

매번 문자열을 조립하려면 가독성도 떨어지고...

공통����������� ������������������  함수를����������� ������������������  만들면����������� ������������������  깔끔할����������� ������������������  듯.

var tmplStr = ‘{who}가 {when}할 때 뽀뽀뽀~’;var result = replaceTemplate(tmplStr, data);$(‘#result’).html(result);

function replaceTemplate(tmplStr, data){ var result = tmplStr; for (var key in data) [ result = result.replace(‘{‘ + key + ‘}’, data[key]); } return result;}

템플릿이����������� ������������������  많아진다면?

var tmplStr = ‘{who}가 {when}할 때 뽀뽀뽀~’;var tmplFoo = ‘...’;var tmplBar = ‘...’;

...

var tmplBaz = ‘...’;

실제 코드보다 템플릿이 더 많아지는 상황.템플릿을 코드에서 분리하자!

DOM에����������� ������������������  넣어볼까?

[main.html]<script id=”ppopo” type=”text/x-template”>{who}가 {when}할 때 뽀뽀뽀~</script>

[main.js]var tmplStr = loadTemplate(‘ppopo’);var result = replacePpopo(tmplStr, data);$(‘#result’).html(result);

function loadTemplate(id) { return document.getElementById(id).innerHTML;}

스크립트����������� ������������������  태그인데?

-����������� ������������������  스크립트����������� ������������������  태그에����������� ������������������  알����������� ������������������  수����������� ������������������  없는����������� ������������������  타입을����������� ������������������  넣으면,

-����������� ������������������  브라우저가����������� ������������������  무시하고����������� ������������������  실행하지����������� ������������������  않음.

-����������� ������������������  스크린����������� ������������������  리더나����������� ������������������  검색����������� ������������������  엔진에서도����������� ������������������  무시함.

-����������� ������������������  적은����������� ������������������  양의����������� ������������������  템플릿을����������� ������������������  간편하게����������� ������������������  처리하고자����������� ������������������  할����������� ������������������  때����������� ������������������  유용함.

더����������� ������������������  많아진다면?

<script id=”ppopo” type=”text/x-template”>{who}가 {when}할 때 뽀뽀뽀~</script><script id=”foo” type=”text/x-template”></script><script id=”bar” type=”text/x-template” ></script>

...

<script id=”baz” type=”text/x-template” ></script>

페이지에 HTML 코드보다 템플릿 코드가 더 많은 상황.파일로 분리하자!

템플릿����������� ������������������  파일을����������� ������������������  불러오자.

[ppopo.tmpl]{who}가 {when}할 때 뽀뽀뽀~

[main.js]loadTemplate(‘ppopo.tmpl’, function (tmplStr) { var result = replaceTemplate(tmplStr, data); $(‘#result’).html(result);});

function loadTemplate(filename, callback) { requestAjax(filename, callback);}

// 비동기이기 때문에 주의해야 함.

템플릿이����������� ������������������  여러����������� ������������������  번����������� ������������������  요청한다면?

loadTemplate(‘ppopo.tmpl’, function () { ... });loadTemplate(‘ppopo.tmpl’, function () { ... });loadTemplate(‘ppopo.tmpl’, function () { ... });

Ajax로 템플릿을 가져오는 비용은 매우 크다.DOM에서 가져오는 것도 마찬가지!

한����������� ������������������  번����������� ������������������  가져온����������� ������������������  건����������� ������������������  캐시해두자!

var cache = {};

function loadTemplate(filename, callback) { if (cache[filename]) { callback(cache[filename]); return; } requestAjax(filename, function (tmplStr) { cache[filename] = tmplStr; callback(tmplStr); });}

loadTemplate(‘ppopo.tmpl’); // 비동기 요청loadTemplate(‘ppopo.tmpl’); // 캐시

템플릿이����������� ������������������  여러����������� ������������������  개라면?

loadTemplate(‘ppopo.tmpl’);loadTemplate(‘foo.tmpl’);loadTemplate(‘bar.tmpl’);

...

loadTemplate(‘baz.tmpl’);

매 파일마다 비동기 요청이 발생한다.템플릿 여러 개를 한 파일에 두면 어떨까?

한����������� ������������������  파일에����������� ������������������  여러����������� ������������������  템플릿을����������� ������������������  두자.

[main.tmpl]<template id=”ppopo”>{who}가 {when}할 때 뽀뽀뽀~</template>

<template id=”foo”></template><template id=”bar”></template>

...

</template id=”baz”></template>

한����������� ������������������  파일에����������� ������������������  여러����������� ������������������  템플릿을����������� ������������������  두자.

[main.js]var tmplMap;

function loadTemplate(filename, id, callback) { if (tmplMap) { callback(tmplMap[id]); // use cached return; } requestAjax(filename, function (tmplList) { tmplMap = parseTemplateList(tmplList); callback(tmplMap[id]); });}

loadTemplate(‘main.tmpl’, ‘ppopo’, function (tmplStr) { ...}

템플릿이����������� ������������������  지금����������� ������������������  필요하지����������� ������������������  않은데?

지금은 아직 택배를 주문하기 전.

뽀뽀 문자열은 택배가 도착할 때나 필요한데,미리 로드할 필요가 있을까?

필요할����������� ������������������  때����������� ������������������  로드하자.

// 특정 버튼을 클릭할 때 로드한다.ppopoButton.on(‘click’, function () {

loadTemplate(‘main.tmpl’, ‘ppopo’, function (tmplStr) { ... });

});

지금까지����������� ������������������  우리가����������� ������������������  만든����������� ������������������  것.

-����������� ������������������  문자열����������� ������������������  치환����������� ������������������  함수.

-����������� ������������������  코드에서����������� ������������������  템플릿����������� ������������������  분리.

-����������� ������������������  비동기로����������� ������������������  템플릿����������� ������������������  로딩����������� ������������������  및����������� ������������������  캐싱.

-����������� ������������������  필요한����������� ������������������  시점으로����������� ������������������  지연����������� ������������������  로딩.

가만...

매번 문자열을 치환하고 있었는데...

function replaceTemplate(tmplStr, data) { var result = tmplStr; for (var key in data) { result = result.replace(‘{‘ + key + ‘}’, data[key]); } return result;}

치환 비용을 줄일 순 없을까?

함수로����������� ������������������  만들어버리자.

// 템플릿을 함수로 만든다. (컴파일)var compiledPpopo = compileTemplate(tmplStr);

// 이후로는 컴파일 한 함수를 호출var result = compiledPpopo(data);

$(‘#result’).html(data);

템플릿����������� ������������������  컴파일.

function compileTemplate(tmplStr) {

// 템플릿을 파싱해 아래 형태의 함수를 리턴한다. // function (data) { // return data.who + ‘가 ‘ + data.when + ‘ 할 때 뽀뽀뽀~’; // }

return function (data) { ... }}

매번 템플릿을 치환하는 비용을 줄일 수 있다.

그럼����������� ������������������  아예����������� ������������������  미리����������� ������������������  컴파일하면?

빌드 과정에서 미리 컴파일한다.

프리 컴파일 결과로 함수 문자열을 생성해 내려주면,클라이언트에서의 컴파일 비용을 줄일 수 있다.

[ ppopo.tmpl, foo.tmpl, bar.tmpl, ..., baz.tmpl ] --(컴파일)--> tmpl.js

템플릿����������� ������������������  프리����������� ������������������  컴파일.

[tmpl.js]var template = { ppopo: function (data) { return data.who + ‘가 ‘ + data.when + ‘할 때 뽀뽀뽀~’; }, foo: function (data) { ... }, bar: function (data) { ... }, ... baz: function (data) { ... }};

[main.js]var result = template.ppopo(data);$(‘#result’).html(result);

다����������� ������������������  만들었다!����������� ������������������  템플릿����������� ������������������  엔진.

-����������� ������������������  템플릿����������� ������������������  문법으로����������� ������������������  문자열����������� ������������������  치환

-����������� ������������������  별도의����������� ������������������  템플릿����������� ������������������  파일

-����������� ������������������  비동기����������� ������������������  로더����������� ������������������  제공

-����������� ������������������  클라이언트����������� ������������������  컴파일����������� ������������������  제공(to����������� ������������������  메모리)

-����������� ������������������  프리����������� ������������������  컴파일����������� ������������������  제공(to����������� ������������������  함수����������� ������������������  문자열)

그����������� ������������������  외����������� ������������������  다른����������� ������������������  기능들

-����������� ������������������  템플릿����������� ������������������  내에서����������� ������������������  자바스크립트����������� ������������������  실행

-����������� ������������������  반복문,����������� ������������������  분기문����������� ������������������  등을����������� ������������������  템플릿����������� ������������������  문법으로����������� ������������������  제공

-����������� ������������������  템플릿����������� ������������������  내에����������� ������������������  다른����������� ������������������  템플릿을����������� ������������������  포함����������� ������������������  (Partials)

-����������� ������������������  클라이언트와����������� ������������������  서버����������� ������������������  사이드����������� ������������������  언어를����������� ������������������  동시에����������� ������������������  지원

템플릿����������� ������������������  엔진,����������� ������������������  어떤����������� ������������������  것들이����������� ������������������  있나?

MicroTemplate,����������� ������������������  EJS,����������� ������������������  Underscore����������� ������������������  Template,

Mustache,����������� ������������������  Handlebars,����������� ������������������  Hogan.js,����������� ������������������  dust.js,����������� ������������������  Jade,����������� ������������������  ...

이����������� ������������������  외에도����������� ������������������  되게����������� ������������������  많다...

어떤����������� ������������������  걸����������� ������������������  선택해야����������� ������������������  할까?

-����������� ������������������  서버에서����������� ������������������  쓰나����������� ������������������  클라이언트에서����������� ������������������  쓰나?

-����������� ������������������  서버와����������� ������������������  클라이언트����������� ������������������  동시에����������� ������������������  사용할����������� ������������������  건가?

-����������� ������������������  템플릿����������� ������������������  내에서����������� ������������������  자바스크립트����������� ������������������  구문을����������� ������������������  실행할����������� ������������������  건가?

-����������� ������������������  템플릿����������� ������������������  내에����������� ������������������  로직을����������� ������������������  포함할����������� ������������������  건가?

-����������� ������������������  http://garann.github.io/template-chooser/

링크드인의����������� ������������������  리서치����������� ������������������  결과

-����������� ������������������  코드����������� ������������������  재사용이����������� ������������������  가능하고����������� ������������������  파샬을����������� ������������������  제공하나?

-����������� ������������������  다국어����������� ������������������  지원하나?

-����������� ������������������  비동기����������� ������������������  로드����������� ������������������  지원하나?

-����������� ������������������  배우기����������� ������������������  쉬운가?

-����������� ������������������  수정����������� ������������������  시����������� ������������������  바로����������� ������������������  확인할����������� ������������������  수����������� ������������������  있나?

-����������� ������������������  성능����������� ������������������  괜찮나?

-����������� ������������������  문서화����������� ������������������  잘����������� ������������������  되어����������� ������������������  있고,����������� ������������������  성숙한����������� ������������������  라이브러리인가?

-����������� ������������������  리서치����������� ������������������  결과����������� ������������������  링크

링크드인의����������� ������������������  리서치����������� ������������������  결과

-����������� ������������������  최총����������� ������������������  선정:����������� ������������������  Dust.js

-����������� ������������������  상위����������� ������������������  랭크:

����������� ������������������  ����������� ������������������  ����������� ������������������  Google����������� ������������������  Closure����������� ������������������  Template,����������� ������������������  Mustache,����������� ������������������  Handlebars

필요하다면,����������� ������������������  이����������� ������������������  템플릿들을����������� ������������������  먼저����������� ������������������  검토해보면����������� ������������������  좋을����������� ������������������  듯!

우리����������� ������������������  팀에서는.

-����������� ������������������  성능이����������� ������������������  중요하다.

-����������� ������������������  프리����������� ������������������  컴파일����������� ������������������  할����������� ������������������  수����������� ������������������  있어야����������� ������������������  한다.

-����������� ������������������  템플릿����������� ������������������  내에����������� ������������������  로직은����������� ������������������  넣지����������� ������������������  않는다.

-����������� ������������������  전달����������� ������������������  인자가����������� ������������������  함수인����������� ������������������  경우����������� ������������������  실행����������� ������������������  가능해야����������� ������������������  한다.

-����������� ������������������  배우기����������� ������������������  쉬워야����������� ������������������  한다.

-����������� ������������������  동기적으로����������� ������������������  처리할����������� ������������������  수����������� ������������������  있어야����������� ������������������  한다.

-->����������� ������������������  Mustache����������� ������������������  선택����������� ������������������  (프리컴파일은����������� ������������������  Handlebars로����������� ������������������  수행)

Dust.js가����������� ������������������  1등이라면서?

dust.render(‘ppopo’,����������� ������������������  function����������� ������������������  (err,����������� ������������������  out)����������� ������������������  {

����������� ������������������  ����������� ������������������  //����������� ������������������  비동기로����������� ������������������  처리

});

프리����������� ������������������  컴파일����������� ������������������  한����������� ������������������  상황이라면,

동기적으로����������� ������������������  사용하는����������� ������������������  게����������� ������������������  좋겠다고����������� ������������������  결정했기����������� ������������������  때문.

선택����������� ������������������  가이드!

-����������� ������������������  프로젝트의����������� ������������������  규모나����������� ������������������  중요도를����������� ������������������  고려해����������� ������������������  선택한다.

-����������� ������������������  컴파일����������� ������������������  할����������� ������������������  수����������� ������������������  있다면,����������� ������������������  성능����������� ������������������  차이는����������� ������������������  크지����������� ������������������  않다.

����������� ������������������  ����������� ������������������  (메모리로의����������� ������������������  컴파일과����������� ������������������  함수����������� ������������������  문자열로의����������� ������������������  컴파일����������� ������������������  혼돈����������� ������������������  주의)

-����������� ������������������  템플릿����������� ������������������  내����������� ������������������  로직이����������� ������������������  많아지면����������� ������������������  디버깅하기����������� ������������������  어렵다.

����������� ������������������  ����������� ������������������  (자동����������� ������������������  생성된����������� ������������������  코드에서����������� ������������������  오류가����������� ������������������  발생한다면?)

-����������� ������������������  템플릿����������� ������������������  문법����������� ������������������  내의����������� ������������������  간단한����������� ������������������  분기나����������� ������������������  반복문은����������� ������������������  효율적이다.

데모����������� ������������������  타임!

-����������� ������������������  팀에서����������� ������������������  사용하는����������� ������������������  템플릿����������� ������������������  코드����������� ������������������  예

-����������� ������������������  템플릿����������� ������������������  자동화����������� ������������������  예제

����������� ������������������  ����������� ������������������  ����������� ������������������  https://github.com/ohgyun/template-example

끝!����������� ������������������  고맙습니다.