2018년 4월 17일 화요일

Node.js - 스터디 4주차 - 정리 정돈의 기술

https://opentutorials.org/course/2136/
생활코딩 강의를 이용해 진행하는 스터디 3+@주차.

4/17(화) :: 37강 'jade - extends' 부터 43강 '글작성 + 인증 (CRUD + Auth)-OrientDB 2' 까지.


완강!!


jade - extends


37강 jade - extends 부터 마지막 강의 까지는 '정리정돈의 기술'이라는 테마로 진행된다. 우선 jade 템플릿 엔진을 사용할 때 중복을 제거할 수 있는 기법이 소개된다. python의 django에서도 나오는 extends ~ block 키워드를 이용하는 방법인데 일종의 템플릿 간 부모-자식 관계를 둬서 중복을 제거하는 기법이다. view에 대한 중복을 제거한다고 해서 성능이 향상되는 것은 아니겠지만 유지보수 등 관리 측면에서 이점이 있기 때문에 공통부는 따로 떼서 관리하는것이 낫다.

1) view.jade와 add.jade가 있는데 공통된 부분이 있다면 따로 떼어내 layout.jade란 파일로 옮겨적는다. 물론 layout.jade란 이름은 임의로 지은 것이며 자유롭게 지정할 수 있다.

2) view.jade, add.jade에서 공통된 부분을 삭제하고 extends ./layout이라 써준다. './layout'은 같은 폴더의 layout.jade를 가리킨다. 만약 layout.jade 파일명이 parent.jade라면 extends ./parent가 된다.

2) 공통 코드가 있는 layout.jade에 block 키워드로 자식 컨텐츠가 들어갈 위치를 지정한다. block의 이름은 예약된 키워드가 아니라면 자유롭게 지정할 수 있다. 예제에서 설명된 layout.jade의 내용은 다음과 같다.
doctype html
html
  head
  body
    ul
      li JavaScript
      li nodejs
      li expressjs
    article
      block content

3) view.jade, add.jade에서 공통된 부분을 삭제하고 extends ./layout이라 써준다. './layout'은 같은 폴더의 layout.jade를 가리킨다. 만약 layout.jade 파일명이 parent.jade라면 extends ./parent가 된다. 그리고 부모가 지정한 block 이름에 대한 내용을 각각 작성하면 된다. 부모가 'block child'라 이름지었다면 자식 view에서도 동일하게 'block child'라 작성해야 전체 컨텐츠가 올바르게 렌더링되는 것을 확인할 수 있다.
extends ./layout
block content
  form
    input(type='text')
    input(type='submit')

유사한 기능으로 include가 있다. include는 특정 jade의 내용을 삽입하는 기능이다. 자주 인용되는 head, header, footer 같은 내용은 extends 구조로 표현하기 보다 include로 처리하는 것이 구조상 낫다고 본다.

사용자 정의 모듈 만들기


자주 참조되는 기능 단위를 모듈로 정의할 수 있다. Node.js에서 모듈은 프로그램 복잡도를 줄이고자 하는 목적이 가장 크겠지만 의미있는 기능 단위를 다른 사람에게 배포할 때도 유용하게 쓰이는 개념이다. 모듈을 정의 방식도 매우 편리한데 제공하고자 하는 대상을 단순히 module.exports로 지정해주면 외부 파일 또는 또다른 모듈에서 이를 참조해 사용하거나 확장할 수 있다.

calculator.js
module.exports.sum = function(a, b) {
  return a + b;
}
module.exports.avg = function(a, b) {
  return (a + b) / 2;
}

example.js
var calc = require('./lib/calculator');
console.log(calc.sum(1, 2));
console.log(calc.avg(1, 2));

라우트 분리하기

모듈 시스템과 비슷한 방식으로 라우트 또한 정리가 가능하다. 복잡한 애플리케이션일수록 애플리케이션의 구조를 더 단순화시킬 필요가 있다. 극단적인 예로 1000개의 라우트를 정의해야 한다면 이를 하나의 파일에서 관리하는 것은 매우 어려울 것이다. 따라서 서로 연관된, 유사한 목적에 따른 라우트끼리 모아 분리된 파일로 관리할 필요가 있다.

라우트를 분리하기 위한 방법은 여러가지가 있는데 express에서 관련된 기능이 제공된다. 바로 Router-level 미들웨어를 사용하면 된다.
var route = express.Router();
route.get('/r1', function(req, res) {
  res.send('Hello /p1/r1');
});
route.get('/r2', function(req, res) {
  res.send('Hello /p1/r2');
});
app.use('/p1', route); // route 변수는 /p1/r1, /p1/r2 URI 처리를 담당하게 된다.

기존 application level express 미들웨어에 모든 라우트 기능을 지정했다면 router level express 미들웨어 선언을 통해 라우트 기능의 일부를 떼낼 수 있다. 위 예제에서와 같이 선언된 변수 route가 처리하는 내용을 별도 파일로 분리해 모듈로 지정하는 방식인데, 기능 단위로 잘 구분해서 라우트를 분할하면 전체 애플리케이션을 보다 편하게 관리할 수 있다.

글작성 + 인증 (CRUD + Auth) - MySQL 1, 2 / OrientDB 1, 2


이전 강의에서 MySQL 버전과 OrientDB 버전으로 작성했던 글작성 애플리케이션과 인증 애플리케이션을 깔끔한 구조로 정리하고 결합하는 것에 대한 강의다.

선 js에 박혀있던 html 내용을 jade로 이동시킨다. 변경할 땐 html2jade.org라는 웹사이트를 이용하면 직접 jade 구문을 작성하지 않고 바로 변환된 결과를 얻을 수 있다. jade의 extends, include 기능을 활용해 공통 부분을 별도 jade 파일로 나누도록 한다.

인증 기능에 대한 내용도 별도의 파일로 분할한다. 인증 기능에 대한 내용을 auth.js로 이동한 뒤 passport를 인자로 받는 모듈 함수를 노출시킨다. 함수 내부엔 router 레벨 미들웨어가 하나 있어서 인증과 관련된 요청에 대한 처리 작업을 수행한다.
module.exports = function (passport) {
    var route = require('express').Router();
    route.post( ...
    ...
}

메인 로직에선 auth.js로 분리한 모듈을 불러와 '/auth/' 하위 요청에 대한 처리를 담당하게끔 위임한다.
var auth = require('./routes/mysql/auth')(passport);
app.use('/auth/', auth);

위와 같은 패턴으로 나머지 기능 단위에 대해서도 파일을 분리해나가면 되는데 강의 내용에 다소 억지스러운 부분이 있어서 크게 와닿진 않는다. 어쨌든 express가 제공하는 라우팅 기능은 좀더 알아둘 필요가 있는 것 같다. 아래 링크를 참고해보자.

댓글 없음:

댓글 쓰기