템플릿 리터럴의 기초

구 표준인 ES6에서 템플릿 문자열(Template String)으로 사용되었으며, 개정된 표준에서는 템플릿 리터럴(Template Literal) 로 사용합니다.

같은 의미이며, 사용법도 동일합니다.

리터럴 표기를 표준으로 사용하면서 용어가 바뀐 것입니다.

자바스크립트 만으로 동적인 웹페이지를 생성할 수 있는 중요한 기능의 하나입니다.

문자열을 템플릿화해서, 배열이나 객체 데이터들을 갈아끼울 수 있는 구조를 언어 상에서 지원합니다.

문자열에 변수 역할을 하는 템플릿 코드를 추가한 후, 자바스크립트 데이터를 대입해 새로운 문자열을 생성할 수 있습니다.

이런 특징을 활용해 반복되는 HTML 의 태그나 목록을 동적으로 생성할 수 있기 때문에, 데이터 기반의 HTML 페이지를 만드는데 활용할 수 있습니다.

별도의 자바스크립트 라이브러리나 확장 기능 처럼 많은 기능을 제공하지는 못하지만, 가볍고 간결한 기능이 최대의 장점입니다.

자바스크립트에는 템플릿 엔진이라고 하는 템플리팅(Templating) 라이브러리들이 상당히 많이 있습니다.

핸들바(Handlebars), EJS, 언더스코어(Underscore) 같은 잘 알려진 템플릿 엔진부터 수십가지의 엔진들이 있습니다.

이들 템플릿 엔진은 자바스크립트를 사용해 동적인 HTML 파일을 생성할 수 있도록 해주는 역할을 합니다.

최근에는 이런 템플릿 엔진들이 MVVM 프레임임워크라고 하는 프론트엔드 프레임워크의 인기에 밀리는 경향이 있지만, 둘은 용도가 살짝 다릅니다.

단순히 동적인 웹 페이지의 생성이 주 목적이라면, 템플릿 엔진이 좀 더 가볍게 동작하고, 사용 방법도 쉽기 때문에 템플릿 엔진쪽이 좀더 적합합니다.

템플릿 엔진은 자바스크립트의 템플릿 리터럴보다 더 강력하고 다양한 기능을 제공하기 때문에 템플릿 리터럴로 기능이 부족할 경우 템플릿 엔진을 사용하는 것이 좋습니다.

템플릿 리터럴의 선언

일반적으로 잘 사용하지 않는 키보드 문자중에 역따옴표가 있습니다. 영어로는 백쿼트(Backquote), 또는 백틱(Backtick) 이라고 합니다.

따옴표, 쌍따옴표로 감싸는 일반 문자열과 달리 역따옴표로 감싸는 문자열을 특별히 템플릿 리터럴이라고 합니다.

let exp = '표시';console.log(`문자열 ${exp}`);console.log(`문자열다음줄 표시`)

템플릿 리터럴은 일반 문자열과 달리 3가지 중요한 특징을 가집니다.

  1. 줄바꿈을 여러줄로 된 문자열로 표현할 수 있습니다. 역슬래시와 조합한 제어문자(\n)가 아닌 에디터 입력기에서 엔터키를 눌러 줄을 바꾼 것을 그대로 유지해줍니다.
  2. 변수, 표현식, 연산식 사용이 가능합니다. 역따옴표로 감싼 문자열 안에 ${expression} 형태로 변수, 연산식 또는 표현식을 대입해 동적으로 바뀌는 문자열을 생성합니다.
  3. 중첩이 가능합니다. `문자열 ${'출력'+${'중첩'}} 과 같은 템플릿 리터럴 중첩 표현이 가능합니다.

이 세가지 특징은 AJAX로 서버에서 가져온 데이터를 HTML 페이지에 동적으로 적용할 수 있도록 하는 중요한 역할을 합니다.

let friends = [{name: '라이언', age: 5}, {name: '어피치', age: 3}, {name: '콘', age: 4}, {name: '프로도', age: 2}];
let template = `<ul><li>이름:${friends[0].name} , 나이: ${friends[0].age}</li><li>이름:${friends[1].name} , 나이: ${friends[1].age}</li><li>이름:${friends[2].name} , 나이: ${friends[2].age}</li><li>이름:${friends[3].name} , 나이: ${friends[3].age}</li></ul>`
console.log(template);

줄바꿈과 탭이 모두 그대로 유지되기 때문에 HTML 페이지에 template 를 붙여넣으면 레이아웃이 깨끗하게 유지되는 HTML 페이지를 생성합니다.

템플릿 리터럴의 끝에는 세미콜론으로 문장의 끝을 표시하지 않아도 됩니다.

중첩과 반복문 구현

조금 더 재사용성을 높이기 위해 템플릿 리터럴의 중첩을 활용해 적은 코드량으로 템플릿 리터럴을 만들어보겠습니다.

훨씬 간결하고, 데이터의 갯수가 변경되는 실제 환경에도 대응할 수 있습니다.

let friends = [{name: '라이언', age: 5}, {name: '어피치', age: 3}, {name: '콘', age: 4}, {name: '프로도', age: 2}];
let template = `<ul>${friends.map(function(friend){return `<li>이름:${friend.name} , 나이: ${friend.age}</li>`}).join('\n')}</ul>`
console.log(template);

<script> 로 템플릿 리터럴을 분리하기

RESTful 로 작성된 API 를 이용한 서비스로 웹 사이트를 제작하는 경우 템플릿 관리는 매우 중요합니다.

자바스크립트로 동적인 페이지를 생성하기 때문에 템플릿을 생성하고 관리하는 주체가 누구인지에 따라 템플릿을 저장하는 위치도 달라져야 합니다.

협업 환경이라면 템플릿 리터럴을 UI 표현으로 봐서 HTML 페이지에, 또는 별도의 자바스크립트 파일에 모아서 관리를 하게 됩니다.

이럴 때 템플릿 리터럴을 분리하기 위해

<script></script>

태그를 사용합니다.

스크립트(자바스크립트) 코드 블록을 HTML 안에 인라인으로 사용하기 위해 사용하는 태그지만

몇가지 트릭을 사용하면 HTML DOM이나 렌더링에 영향을 주지 않으면서 HTML 문서 안에 템플릿 리터럴을 정의하고 사용할 수 있습니다.

아래와 같은 템플릿 리터럴을 </body> 밑에 추가해주면 됩니다.

<script id="templateliteral">`<ul>${friends.map(function(friend){return `<li>이름:${friend.name} , 나이: ${friend.age}</li>`}).join('\n')}</ul>`</script>

이렇게 템플릿 리터럴을 <script> 태그로 감싸 HTML 파일에 삽입하면, 웹브라우저는 이 태그 안의 내용을 스크립트 블록으로 인식하고 DOM 구조 생성에서 배제합니다. 반대로 자바스크립트 파서는 이 코드가 할당되지 않은 템플릿 리터럴이므로 그냥 통과합니다.

<script> 태그에 아이디(id)를 부여한 것은 자바스크립트에서 쿼리선택자(Query Selector)로 이 태그 안의 내용을 가져오기 위해서입니다.

말했듯이 자바스크립트는 <script> 태그 안의 내용을 HTML 태그로 인식합니다.

let friends = [{name: '라이언', age: 5}, {name: '어피치', age: 3}, {name: '콘', age: 4}, {name: '프로도', age: 2}];//eval()은 문자열로 된 자바스크립트 코드를 실행할 수 있는 코드로 변경합니다.document.addEventListener('DOMContentLoaded', function(){    let template = eval(document.getElementById('templateliteral').innerHTML);    console.log(template);});

템플릿 리터럴이 분리되어 UI단의 출력을 별도로 관리할 수 있게 되었고, 자바스크립트 코드는 기능적인 변화가 없는 한은 다시 수정할 필요가 없어졌습니다.

이런 방식의 구현은 특히 팀프로젝트나 협업에서 중요합니다.

디자이너는 템플릿 리터럴을 포함한 HTML 구조 생성 작업에 HTML 파일만을 수정하고 관리하면 됩니다. 

커밋도 HTML 파일만 하면 되기 때문에 다른 협업자와의 코드 간섭도 없게 됩니다.

자바스크립트 개발자는 AJAX로 JSON 데이터를 받아서 HTML 파일의 템플릿 리터럴을 끌어와 대입만 해주면 되기 때문에 서버, 또는 API 서비스에서 오는 서버사이드 데이터와 디자인 단의 템플릿 리터럴에 신경 쓸 필요가 없습니다.

화면에 표시하는 HTML 템플릿 리터럴의 태그 표현이 바뀌더라도 자바스크립트 개발자는 신경 쓸 필요가 없게 됩니다.