프레임워크/Express

[2차 정리]템플릿 엔진

빨대도둑 2023. 9. 7. 01:09

정적파일, 동적 파일

정적 파일과 동적 파일의 큰 차이점은 프로그래밍적으로 웹 페이지가 만들어졌는냐의 여부 입니다.

HTML, CSS, JS 파일과 같이 한번 만들어진 자원이 언제나 똑같이 보이는 리소스를 ‘정적파일’ 이라고 합니다.

‘동적파일’은 사용자와 서버가 상호작용하며 페이지 내용의 일부 혹은 전부가 그때그때 생성되는 파일 입니다.

정적 파일(static file)

장점

  • HTML 파일 적성이 편하다
  • 서버를 재시작 하지 않아도 바로 반영할 수 있다.
  • 라우터 설정을 하지 않아도 자동으로 설정된다.

단점

  • 프로그래밍적인 요소를 사용할 수 없으므로 반복되는 HTML코드 작성을 피하기 힘들다

동적 파일(dynamic file)

장점

  • 프로그래밍적인 요소를 사용하여 코드를 줄일 수 있다.
  • 클라이언트와 서버와의 상호작용을 반영할 수 있다.

단점

  • JS 파일 안에서 HTML 파일 작성하는 것이 불편하다
  • 서버를 재시작해야 변경사항이 반영된다. (단 nodemon을 통해서 해결할 수 있다)

정적 파일과 동적 파일은 장점과 단점이 서로 균형(Trade-off)를 이룬다.

따라서 둘 중 하나만 골라서 서비스해야 할 필요는 없고 ‘템플릿 엔진’을 사용하면 된다.

‘템플릿 엔진’을 사용하면 정적 파일의 장점과 동적 파일의 장점을 모두 얻을 수 있다.


템플릿엔진: Template Engine

템플릿 양식과 특정 데이터 모델에 따른 입력 자료를 합성하여 결과 문서를 출력하는 소프트웨어

템플릿 엔진은 정적파일과 동적파일의 장점만을 합친 기술로 html을 작성하기 편하고, 변수도 사용할 수 있고, 변경사항을 반영하기 위해 서버를 재시작 할 필요 없는 기술입니다.

 

 

예전의 서버에서는 데이터베이스에서 데이터를 가져올 때마다 html 파일을 새로 만들어 렌더링 하는 방식을 사용했습니다.

아주 일부의 데이터만 변경되더라도 전체 페이지를 새로 그려야 했습니다.

이 후 ajax가 등장하면서 ajax를 통해 요청을 보내면 서버는 요청한 데이터만 건네주고, 페이지 가공은 클라이언트가 맡았습니다.

하지만 ajax 방식도 손이 많이 가는 방식이었습니다.

그래서 템플릿 엔진이라는 것이 등장했고, 템플릿엔진을 이용해서 런타임 시 프로그래밍적인 기법(변수사용, 조건문, 반복문 등)을 사용해서 데이터를 가공할 수 있게 되었습니다.

템플릿 엔진을 사용하면 템플릿 파일(ejs, pug)내의 변수를 서버에서 제공할 수 있는 값(actual value)로 변환되고 이는 정적 html 파일로 변환하여 클라이언트로 보내줍니다.

 


장점

코드량을 줄일 수 있다.

템플릿 파일은 기존의 html 보다 간단한 문법을 사용하기 때문에, 코드량을 줄일 수 있습니다.

재사용성이 높다

페이지에서 바뀌지 않는 부분(헤더, 내비게이션 등)을 템플릿 파일로 만들어 놓고 여기서 데이터에 따라 바뀌는 부분만 렌더링할 수 있으므로 템플릿 파일의 재사용성이 높아집니다.

유지보수가 용이하다

 


템플릿 엔진의 종류

pug(jade)

장점

  • 기능이 다양하고 활용도가 높다

단점

  • html문법과 상이하다
  • 오픈소스 html문법을 그대로 가져다 쓸 때 pug 문법으로 수정해야 한다.

 


 

ejs

장점

  • pug보다 빠르다
  • 오류 처리가 수월하다
  • html과 문법이 동일하다

단점

  • <%%>태그를 삽입해서 if, for문 작성시 코드가 난잡해 보일 수 있다.

 


 

Handlebars

장점

  • partials 기능을 지원한다.
  • 로딩이 빠르다
  • 로직과 makrup이 깔끔하게 분리된다

단점

  • 레이아웃 기능이 없다
  • 자동완성, syntax 하이라이팅 기능을 지원하지 않는다

 


 

nunjucks

장점

  • pug의 이질적인 문법에 적응하기 힘든 사람한테 좋다
  • html 문법 그대로 사용한다

단점

  • 다른 템플릿 엔진보다 많이 사용하지 않는다

 


 

EJS: EMbeded JavaScript Tmplate

자바스크립트가 내장되어 있는 html 파일이라는 뜻

기존의 html에서 <%%>태그 안에 자바스크립트 코드와 자바스크립트 객체를 삽입하여 서버의 데이터를 사용할 수 있다

<!DOCTYPE html>
<html>
  <head>
    <title>Title</title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1>Title</h1>
    <p>This is html file</p>
  </body>
</html>
<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel="stylesheet" href="/stylesheets/style.css" />
  </head>
  <body>
    <h1><%= title %></h1>
    <p>This is ejs file</p>
  </body>
</html>

두개의 코드는 같은 코드이다.

ejs를 사용하면 <%자바스크립트 코드%>,<%출력할 자바스크립트 객체%> 이 두 가지 문법만 추가하여 기본의 html문법 방식으로 템플릿 파일을 생성할 수 있다.

 

EJS 문법

const path = require('path');
const express = require('express');
const app = express();

app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views')
app.set('view engine', 'ejs');

app.get('/', (req, res) => {
    res.render('index', {
// ejs 파일로 title이라는 변수와 people이라는 객체를 넘겨줌
// ejs로 변수가 보내지면 ejs는 <%%>태그를 통해 해당 변수를 받아 결과에 표시할 수 있다. 
// 자바스크립트 로직을 작성하는 부분을 <%자바스크립트 코드%> 태그로 감싸주면 되고, 줄바꿈을 하면 새로운 <%%> 태그를 추가해야 한다. 
// 출력할 값에 해당하는 변수는 <%=출력할 자바스크립트 변수(객체)%> 를 사용하고, <%-%>로 표기할 수 있다. 
// 주석처리는 <%# 주석 %> 태그로 한다.
        "People":
            [
                {
                    "name": "Gildong",
                    "age": "15"
                },
                {
                    "name": "Jinsu",
                    "age": "27"
                },
                {
                    "name": "Hyena",
                    "age": "25"
                }
            ]
        , title: "Express"
    });
});

app.listen(app.get('port'), () => {
    console.log(app.get('port'), '번 포트에서 서버 실행 중 ..')
});

 

<!--index.ejs-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><%= title %></title>  
</head>
<body>
    <h1><%= title %></h1>
    <% for (var i = 0; i < People.length; i++) { %>
        <p>Welcome to <%- People[i].name %></p>
        <% } %>  
</body>
</html>

 


 

주의할 점

  • <%%>태그 사용시 줄바꿈이 적용되지 않는다. 따라서 <%%>를 추가해서 줄바꿈을 해주거나 한 줄 로 작성해야 한다.
  • <%%>로 태그를 적용하면 scope가 적용되지 않기 때문에 같은 변수명을 가져도 다른 변수로 인식한다.
  • <%=%> 태그 안의 변수는 타입이 없으므로 문자열로 지정하려면 “<%=%>”처럼 “” 로 감싸주어야 한다.
<!--index.ejs-->
<!DOCTYPE html>  
<html>  
    <head>  
        <%- include('./partials/head'); %>  
    </head>  
    
    <header>  
    <%- include('./partials/header'); %>  
    </header>  
    
    <body>  
        <h1><%= menu %></h1>  
        <p><%= menu %>의 본문 부분 입니다.</p>     
    </body>  
    
    <footer>  
        <%- include('./partials/footer'); %>  
    </footer>  
</html>

<%-include(경로)%> 태그를 사용해서 조각 퍼즐을 하나의 파일로 맞춤

 

const app = express();

app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views')
app.set('view engine', 'ejs');

/* GET home page. */
app.get('/', function (req, res, next) {
    res.render('index2', { menu: "Home" });
});

app.get('/menu1', function (req, res, next) {
    res.render('index2', { menu: "Menu1" });
});

app.get('/menu2', function (req, res, next) {
    res.render('index2', { menu: "Menu2" });
});

app.get('/menu3', function (req, res, next) {
    res.render('index2', { menu: "Menu3" });
});

app.listen(app.get('port'), () => {
    console.log(app.get('port'), '번 포트에서 서버 실행 중 ..')
});

총 세 개의 메뉴를 만들었는데, 각 메뉴의 라우터를 해당 자바스크립트 파일에서 생성함

menu라는 변수를 각 메뉴의 이름과 동일한 문자열로 넣어주고 index.ejs로 보내주어 각 메뉴마다 출력되는 변수가 다르게 구성함.