템플릿 엔진이란?

  • 템플릿 작성 문법과 작성된 템플릿을 HTML로 변환하는 기능을 제공


위 사진과 같이 서버에서 클라이언트로 보낼 HTML의 형태를 미리 탬플릿으로 저장 ->
동작 시에 미리 작성된 템플릿에 데이터를 넣어서 완성된 HTML 생성

Express.js의 템플릿 엔진 종류

  1. EJS - html과 유사한 문법의 템플릿 엔진
  2. Mustache - 간단한 데이터 치환 정도만 제공하는 경령화된 템플릿 엔진
  3. PUG - 들여쓰기 표현식을 이용한 간략하 표기와 레이아웃 등 강력한 기능을 제공

PUG (이번 강의에서 사용한 템플릿 엔진)

  • 들여쓰기 표현식을 이용해 가독성이 좋고 개발 생산성이 높음
  • HTML을 잘 모르더라도 문법적 실수를 줄일 수 있음
  • layout, include, mixin등 강력한 기능 제공
//코드 예시
html
	head			// HTML 닫기 태그없이 들여쓰기로 블럭을 구분
    	title = title // = 을 이용해서 전달받은 변수 사용 가능
    body
    	h1#greeting 안녕하세요
        a.link(href="/") 홈으로 // id나 class 태그 뒤에 이어서 바로 사용 () 을 이용해서 attribute 사용

PUG 문법 소개

each item in arr		//each ~in 표현식으로 주어진 배열의 값 순환하며 HTML 태그 만들 수 있음
	if item.name == 'new' // if, else if, else를 이용해 주어진 값의 조건을 확인하여 HTML 태그 만들 수 있음
		h1 New Document
    else
      h1= `${item.name}`
--- layout.pug ---
html				//block을 포함한 템플릿을 선언하면 해당 템플릿을 layout으로 사용할 수 있음
	head
		title= title
	body
		block content
--- main.pug ---
extends layout		// layout을 extends하면 block 부분에 작성한 HTML 태그가 포함됨
block content		// 반복되는 웹사이트의 틀을 작성해 두고 extends 하며 개발하면 매우 편리하게 쓸 수 있음
	h1 Main Page
---title.pug---
h1= title
---main.pug
extend layout
block content
	include title		// 자주 반복되는 구문을 미리 작성 후 include하여 사용할 수 있음
	div.content			// 일반적인 텍스트 파일도 include하여 템플릿에 포함 가능
		안녕하세요
	pre
		include article.txt
--- listItem.pug ---
mixin listItem(title, name) // mixin을 사용하여 템플릿을 함수처럼 사용할 수 있게 선언할 수 있음
	tr
		td title
		td name
--- main.pug ---
include listItem		//include는 값을 지정할 수 없지만 mixin은 파라미터를 지정하여 값을 넘겨받아 템플릿에 사용 가능
table
	tbody
		listItem('제목','이름')

CRUD란?

Create, Read, Update, Delete

  • 데이터를 다루는 네가지 기본적인 기능
  • 위 네가지에 대한 구현이 가능해야 서비스 개발에 필요한 요구사항을 충족할 수 있음

Create (생성)

  • 게시판을 예로 들면, 게시물 작성에 해당한다

Read (읽기)

  • 게시판을 예로 들면 게시글의 목록과 게시글의 상세를 보는 것에 해당한다

Update (갱신)

  • 게시물에서 게시글을 수정하는 것에 해당한다

Delete (삭제)

  • 게시판에서 게시글을 삭제하는 것에 해당한다

request handler의 오류처리

  • async의 비동기 처리는 매우 편리하지만, 매번 try - catch 구문을 작성하는 것은 귀찮고 실수하기 쉽다
  • request handler를 async function으로 작성하면서 try ~ catch, next를 자동으로 할 수 있도록 구성한 아이디어
const asyncHandler = (requestHandler) => { //asyncHandler는 requestHandler를 매개변수로 갖는 함수형 미들웨어
	return async (req, res, next) => { //전달된 requestHandler는 try ~catch로 감싸져 asyncHandler 내에서 실행된다
		try {
		await requestHandler(req, res);
		} catch (err) {
		next(err);
		}
	}
}
---
router.get('/', asyncHandler(async (req, res) => {
	const posts = await Posts.find({});
	if (posts.length < 1) {
		throw new Error('Not Found'); //throw되는 에러는 자동으로 오류처리 미들웨어로 전달되도록 구성
	}
	res.render('posts/list', { posts });
});

Pagination

  • 데이터가 많아지면 한 페이지에 모든 데이터 표현이 어려움
  • 페이지네이션은 데이터를 균일한 수로 나누어 페이지로 분리하는 것
router.get(... => {
	const page =					// page - 현재 페이지
		Number(req.query.page || 1)
	const perPage =					//perPage - 페이지 당 게시글 수
		Number(req.query.perPage || 10) //query는 문자열로 전달되기 때문에 Number로 형변환이 필요함
    ///posts?page=1&perPage=10 일반적으로 url query 를 사용해 전달
 ...
//MongoDB 의 limit과 skip을 사용하여 pagination 구현 가능
router.get(... => {
	...
	const total = await Post
		.countDocument({});
	const posts = await Post.find({})
		.sort({ createdAt: -1 }) //pagination 시에는 데이터의 순서가 유지될 수 있도록 sort를 사용할 수 있도록 함
		.skip(perPage * (page - 1)) //skip - 검색 시 포함하지 않을 데이터 수
		.limit(perPage); //limit - 검색 결과 수 제한
	const totalPage =
		Math.ceil(total / perPage);
...
//pagination을 mixin으로 선언
mixin pagination(path)
	p
		- for(let i = 1; i <= totalPage; i++)
			a(href=`${path}?page=${i}&perPage=${perPage}`)
		if i == page
			b= i
		else
			= i
		= " "
---
//pagination이 필요한 페이지에서 해당 템플릿을 include한 후, +pagination으로 mixin 을 사용 함
include pagination
tr
	td
		+pagination("/posts")

PM2 Process Manager

  • Node.js 작업을 관리해주는 Process Manager
  • node 명령어로 실행 시 오류 발생이나 실행 상태 관리를 할 수 없음
  • pm2 는 작업 관리를 위한 다양한 유용한 기능을 제공해 줌

PM2를 사용하는 이유

  1. 안정적인 프로세스 실행- 오류발생 시 자동 재실행
  2. 빠른 개발환경– 소스 코드 변경 시 자동 재실행
  3. 배포 시 편리한 관리- pm2 에 모든 프로세스를 한 번에 관리

PM2 사용 방법

//$ pm2 init simple 혹은 $ pm2 init 명령어를 이용하여 pm2 설정파일 예제를 만들 수 있음.
module.exports = {
	apps : [{
		name: 'simple-board',
		script: './bin/www',
		watch: '.',
		ignore_watch: 'views',
	}],
};
---
$ pm2 start
profile
성장하고 싶은 프론트엔드

0개의 댓글

Powered by GraphCDN, the GraphQL CDN