NodeJS: 콤포넌트 만들기

모듈 방식의 express 콤포넌트 만들기

코드 기반 모듈화 하기

Modular nodejs express 를 정리했다.

모듈식 구조는 콤포넌트 사이를 완전히 분리되지 않는 것으로 이해할 수 있다. 모듈화 구조는:

    1. 작은 콤포넌트로 나뉜다
    1. 콤포넌트 자체의 의존성 (테스트)를 갖고 타 콤포넌트에 영향을 최소화해 갱신할 수 있다.
    1. 프로젝트 전반 의존성은 개별 콤포넌트낄 공유 (혹은 덮어씀)할 수 있다
    1. 콤퍼넌트 우선-클래스(first-class)를 만들어야 한다. 즉 상대적인 경로롤 require를 구문을 사용 않는다.
    1. 다시 구성할 필요 없이앱 확장 (혹은 축소)에 전념한다

최소 모듈식 구조

아래 같은 최소 구조를 기반으로 하자:

1
2
3
4
bin/
lib/
package.json
index.js
  • bin: npm 스크립에 내장하지 않는 모든것 (ex. hooks, ci 등등 )
  • lib: 앱 콤포넌트

콤포넌트를 추가

콤포넌트는 단독으로 사용할 수 있는 프로젝트의 모든 측면이다. 예를 들어, 한 구성 요소는 cron 작업 스케줄링, 전자 메일 보내기, 내보내기 도구에 다른 구성 작업을 할 수 있다. 데이터 측면에서 모든 모델에 전용 인 하나의 구성 요소 또는 각 모델에 대해 별도의 구성 요소를 가질 수 있다

lib 디렉토리에 콤포넌트를 추가한다:

1
2
3
4
5
6
7
8
9
10
bin/
lib/
|- app/
| |- index.js
| └─ package.json
|- logger/
|- config/
└─ models/
package.json
index.js

콤포넌트의 진입점은 index.js 이고 package.json에 관련 의존성을 담는다.

package.json은 npm init -y 으로 초기화한다.

먼저 express 모듈을 설치한다. ( 여기선 npm version 5 이상 사용)

1
npm i express

logger 디렉토리에 로깅 모듈을 설치하고, config 디렉토리에 콤포넌트를 위한 구성 파일을 둔다.

콤포넌트 우선 클래스 만들기

콤포넌트는 앱에서 우선 클래스 이라서 프로젝트 어느 곳에서든 바로 접근할 수 있어야 해서, 아래 같이 상대적 경로를 사용하지 말아야 한다.

1
var logger = require('../../../logger')

콤포넌트에서 모든 모듈은 /lib 폴더를 참조하게 하므로 아래 같이 트릭을 사용해 node_modules 밑에 _ 로 링크를 만들어 주면
In UNIX, this is:

1
2
cd {project_root}/node_modules
ln -s ../lib _

In Windows, it is:

1
2
cd {project_root}/node_modules
mklink /D _ ..\lib

require('_/looger) 같이 참조할 수 있다.

1
var log = require('_/logger')

의존성 공유

이제 프로젝트 루트에서 콤포넌트를 설치하면 의존성을 사용할 수 있다.

설정

콤포넌트의 분리는 휼륭하다

preinstall

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var fs = require("fs");
var resolve = require("path").resolve;
var join = require("path").join;
var cp = require("child_process");

// get library path
var lib = resolve(__dirname, "../lib/");

fs.readdirSync(lib).forEach(function (mod) {
var modPath = join(lib, mod);

// ensure path has package.json
if (!fs.existsSync(join(modPath, "package.json"))) return;

// install folder
cp.spawn("npm", ["i"], { env: process.env, cwd: modPath, stdio: "inherit" });
});

참조

Nodejs middleware: Express

Express

Express는 NodeJS Webapplication framework이다.

Install express

Express는 크게 express 모듈과 CLI 모듈로 구성되어 있다.

  • express-generator: Express 프로젝트 및 템플릿 생성
  • exporess module: Node.js module

expres 명령을 이용해서 프로젝트를 생성하는 모듈로서 글로벌로 설치합니다.

1
2
$ mkdir myapp
$ cd myapp

npm의 package.json 를 초기화하자.

1
$ npm init

entry point: 에 app.js 혹은 index.js 시작점을 선언한다.

그리고 현재 프로젝트에 express 모듈을 설치하고 package.json에 의존성을 추가해 준다.

npm 5.0+ 이상은 npm install 시 모듈을 의존성 목록에 자동으로 추가한다.

1
$ npm install express

이전 버전은 아래같인 --save 를 명시해야 한다.

1
$ npm install express --save

Express Generator

express-generator 모듈은 손쉽게 프로젝트를 구성할 수 있게 해준다. CLI 명령으로 글로벌로 설치해 준다.

1
$ npm i -g express-generator

pug 뷰 엔진을 가진 myapp 이란 프로젝트를 생성하려면

1
$ express --view=pug myapp

프로젝트로 이동해 모듈을 설치하고 시작한다.

1
$ cd myapp && npm install

MacOS or Linux 에서 디버그 모드로 시작한다.

1
$ DEBUG=myapp:* npm start

Windows 에서

1
> set DEBUG=myapp:* & npm start

debug module

https://developer.ibm.com/node/2016/10/12/the-node-js-debug-module-advanced-usage/

https://expressjs.com/en/guide/writing-middleware.html

ExpressJS Middlewares

  • morgan:
    logger

  • body-parser:
    parse the body so you can access parameters in requests in req.body. e.g. req.body.name.

  • cookie-parser:
    parse the cookies so you can access parameters in cookies req.cookies. e.g. req.cookies.name.

  • serve-favicon:
    exactly that, serve favicon from route /favicon.ico. Should be call on the top before any other routing/middleware takes place to avoids unnecessary parsing.

주요 미들웨어

The following middlewares are not added by default, but it’s nice to know they exist at least:

  • compression:
    compress all request. e.g. app.use(compression())

  • session:
    create sessions. e.g. app.use(session({secret: 'Secr3t'}))

  • method-override:
    app.use(methodOverride('_method')) Override methods to the one specified on the _method param. e.g. GET /resource/1?_method=DELETE will become DELETE /resource/1.

  • response-time: app.use(responseTime()) adds X-Response-Time header to responses.

  • errorhandler:
    Aid development, by sending full error stack traces to the client when an error occurs. app.use(errorhandler()). It is good practice to surround it with an if statement to check process.env.NODE_ENV === ‘development’.

  • vhost:
    Allows you to use different stack of middlewares depending on the request hostname. e.g. app.use(vhost(‘.user.local’, userapp)) and app.use(vhost(‘assets-.example.com’, staticapp)) where userapp and staticapp are different express instances with different middlewares.

  • csurf:
    Adds a Cross-site request forgery (CSRF) protection by adding a token to responds either via session or cookie-parser middleware. app.use(csrf());

  • timeout:
    halt execution if it takes more that a given time. e.g. app.use(timeout(‘5s’));. However you need to check by yourself under every request with a middleware that checks if (!req.timedout) next();.