[JS] 템플레이팅

hye0n.gyu·2024년 9월 26일

백엔드 환경

목록 보기
4/7
post-thumbnail

⭐ 템플레이팅 개요

템플레이팅(Templating) 은 주로 웹 개발에서 사용되는 기법으로, 동적인 콘텐츠를 생성할 때 미리 정의된 형식(템플릿)을 이용하는 것이다.

템플릿은 HTML, XML, JSON 등 다양한 형식으로 작성될 수 있으며, 주로 데이터와 템플릿의 결합을 통해 최종 결과물을 만든다.

Express는 여러 템플릿 엔진을 지원하며, 가장 일반적으로 사용되는 것들은 EJS, Pug(구 Jade), Handlebars 등이 있다.


✔ 템플릿 엔진의 장점

  • 동적 데이터 처리 : 데이터에 따라 다양한 콘텐츠를 쉽게 생성할 수 있다.

  • 가독성 : HTML 코드와 데이터가 분리되어 있어 코드가 더 깔끔해진다.

  • 재사용성 : 동일한 템플릿을 다양한 데이터와 함께 재사용할 수 있다.



⭐ EJS 템플릿 엔진 설정

1. Express 앱 설치 및 기본 설정

npm install express ejs

2. 템플릿 파일 생성

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

// 템플릿 엔진 설정
app.set('view engine', 'ejs');
app.set('views', __dirname + '/views');

app.set('view engine',engine): 사용할 템플릿 엔진을 지정한다. 위의 예에서는 EJS를 사용한다.
app.set('views', path): 템플릿 파일이 위치한 디렉터리를 지정한다.

__dirname 은 Node.js에서 사용되는 전역 변수로, 현재 실행 중인 스크립트 파일의 디렉터리 경로이다.


path 모듈
app.set('views', __dirname + '/views'); 부분은 path 모듈을 사용하여
app.set('views', path.join(__dirname,'/views')) 로 바꿀 수 있다.


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

// EJS 템플릿 엔진 설정
app.set('view engine', 'ejs');
app.set('views', __dirname + '/views');

app.get('/', (req, res) => {
    const title = '홈페이지';
    const message = '안녕하세요, EJS를 사용한 페이지입니다!';
    res.render('index', { title, message }); // 'index.ejs' 파일 렌더링
});

app.listen(3000, () => {
    console.log('서버가 3000번 포트에서 실행 중입니다.');
});


⭐ EJS 보간 구문

✔ 1. <%= %> (HTML 이스케이프 처리)

<%= %> 은 JavaScript 표현식을 평가하고 결과를 HTML로 출력한다. 이 때, HTML 이스케이프가 적용되어 HTML 태그가 있는 경우에는 태그가 안전하게 출력된다. HTML 태그 적용 X

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>사용자 페이지</title>
</head>
<body>
    <h1>안녕하세요, <%= user.name %>님!</h1>
</body>
</html>

✔ 2. <%- %> (HTML 이스케이프 해제)

<%- %> 은 JavaScript 표현식을 평가하고 결과를 HTML로 출력한다. 이 경우, HTML 이스케이프가 적용되지 않으므로 HTML 태그가 그대로 해석된다. HTML 태그 적용 O

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>아이템 목록</title>
</head>
<body>
    <h2>구매한 아이템:</h2>
    <ul>
        <%- itemsHTML %>
    </ul>
</body>
</html>

만약 itemsHTML의 값이 <li>사과</li><li>바나나</li><li>체리</li>라면, 출력 결과는:

<ul>
    <li>사과</li>
    <li>바나나</li>
    <li>체리</li>
</ul>

✔ 3. <% %> (avaScript 코드를 삽입 및 실행)

<% %> 구문은 JavaScript 코드를 실행하기 위해 사용되며, HTML로 출력되지 않는다.
이 구문을 통해 조건문, 반복문 등을 작성하여 동적인 콘텐츠를 생성할 수 있다.

<ul>
<% users.forEach(function(user) { %>
    <li><%= user.name %></li>
<% }); %>
</ul>

세 구문의 차이
<%= %>: HTML 이스케이프 처리된 값을 출력 (안전한 출력 이므로 태그 해석 X)
<%- %>: HTML 이스케이프 해제된 값을 출력 (태그 해석)
<% %>: JavaScript 코드를 실행 (HTML로 출력 없음)



⭐ express 정적 Assets

Express.js에서 정적 assetsHTML, CSS, JavaScript 파일, 이미지, 폰트 등과 같이 서버에서 직접 제공하는 파일들을 의미한다. 이러한 정적 파일들은 클라이언트가 요청할 때 서버가 직접 응답하여 브라우저에 표시된다.


✔ 사용법

js 코드

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

const app = express();

// 정적 파일을 제공할 폴더 설정
app.use(express.static(path.join(__dirname, 'public')));

폴더 구조

├── public
│   ├── css
│   │   └── styles.css
│   ├── js
│   │   └── script.js
│   ├── images
│   │   └── logo.png
│   └── index.html
└── server.js

정적 assets를 활용한 파일 접근

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>정적 Assets 활용</title>
    <link rel="stylesheet" href="/css/styles.css"> <!-- CSS 파일 -->
</head>
<body>
    <header>
        <img src="/images/logo.png" alt="로고"> <!-- 이미지 파일 -->
        <h1>안녕하세요, EJS와 정적 파일!</h1>
    </header>
    
    <p>이 페이지는 EJS 템플릿을 사용하고 있습니다.</p>
    
    <script src="/js/script.js"></script> <!-- JavaScript 파일 -->
</body>
</html>

/public을 경로에 붙이지 않는 이유
/public을 경로에 붙이지 않는 이유는 Express.js에서 express.static 미들웨어를 사용하여 public 폴더를 정적 파일의 기본 제공 경로로 설정했기 때문이다.


✔ 정적 파일(static file)의 정의

Javascript, CSS, Image 등 웹 서비스에서 사용하기 위해 미리 서버에 저장해 놓은 파일이다.

파일 자체가 고정되어 있고, 서비스 중에도 추가되거나 변경되지 않는다.
우리가 페이지를 만들 때 쓰임이 정해져있는 파일들이기 때문에 개발하는 단계에서 이러한 파일들을 관리한다.

외부 환경에 관계 없이 일정한 결과값을 제공해주는 걸 의미한다.


✔ 정적 Assets의 장점

정적 Assets동적 경로 설정(직접 파일의 경로를 지정)을 할 때보다 경로가 간결 하고 관리가 용이하며, 성능보안 측면에서 유리하다.

  • 서버 자원 최적화
    낮은 처리 비용: 정적 파일은 서버에서 직접 파일을 읽고 전송하는 간단한 작업이다. 동적 파일은 데이터베이스 쿼리, 템플릿 렌더링 등 복잡한 처리가 필요하여 서버 자원을 더 많이 소모한다.
    CPU 사용 감소: 정적 파일은 서버가 계산이나 로직을 수행할 필요가 없기 때문에 CPU 사용량이 적다.
  • 응답 속도 향상
    빠른 전송: 정적 파일은 미리 생성되어 있기 때문에 클라이언트 요청에 대해 즉시 응답할 수 있다. 동적 페이지는 처리 시간이 필요해 상대적으로 느리다.
    캐싱: 브라우저와 CDN은 정적 파일을 캐싱할 수 있다. 이렇게 하면 동일한 파일을 요청할 때 서버에 다시 요청할 필요가 없어져 응답 속도가 빨라진다.
  • 보안성
    코드 노출 최소화: 정적 파일은 서버의 로직이나 데이터베이스에 접근할 필요가 없어 보안이 강화된다. 사용자가 요청할 수 있는 파일만 노출되므로 잠재적인 공격 면이 줄어든다.
    정적 검증 가능: 정적 파일은 사전에 검토되고 배포되기 때문에, 배포 시 코드 오류나 취약점을 쉽게 점검할 수 있다.


⭐ EJS와 파일 분할

EJS 파일 분할은 대규모 애플리케이션에서 코드의 재사용성과 유지 관리를 향상시키기 위해 템플릿을 여러 파일로 나누는 방법이다.

이를 통해 각 파일의 책임을 명확히 하고, 가독성을 높이며, 코드 중복을 줄일 수 있다.


EJS와 파일 분할 예제

예제 구조

my-app/
├── views/
│   ├── partials/
│   │   ├── header.ejs
│   │   ├── footer.ejs
│   │   └── sidebar.ejs
│   └── pages/
│       ├── index.ejs
│       └── about.ejs
│   
└── server.js

기본 레이아웃 파일 (layout.ejs)

주 템플릿 파일로, 다른 템플릿을 포함할 기본 구조를 정의합니다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title><%= title %></title>
    <link rel="stylesheet" href="/css/styles.css">
</head>
<body>
    <%- include('partials/header'); %> <!-- 헤더 포함 -->
    <div class="container">
        <%- body; %> <!-- 페이지별 콘텐츠 -->
    </div>
    <%- include('partials/footer'); %> <!-- 푸터 포함 -->
</body>
</html>

헤더 파일 (header.ejs)

헤더 부분을 별도로 정의합니다.

<header>
    <h1>내 웹사이트</h1>
    <nav>
        <ul>
            <li><a href="/"></a></li>
            <li><a href="/about">소개</a></li>
        </ul>
    </nav>
</header>

푸터 파일 (footer.ejs)

푸터 부분을 정의합니다.

<footer>
    <p>&copy; 2024 내 웹사이트. 모든 권리 보유.</p>
</footer>

서버 설정 (server.js)

EJS를 설정하고 요청을 처리합니다.

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

const app = express();

// EJS 설정
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));

app.get('/', (req, res) => {
    res.render('pages/index', { title: '홈페이지', body: '<h2>홈페이지 내용</h2>' });
});

app.get('/about', (req, res) => {
    res.render('pages/about', { title: '소개', body: '<h2>소개 페이지 내용</h2>' });
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
    console.log(`서버가 ${PORT}번 포트에서 실행 중입니다.`);
});
profile
반려묘 하루 velog

0개의 댓글