Express 초기환경 세팅

류예린·2022년 8월 3일
5
post-custom-banner

1. Express 설치


✅ 설치 방법

프로젝트를 진행할 폴더를 만들고 해당 경로로 진입.

$ mkdir myapp
$ cd myapp

아래의 npm init -y 명령어를 사용하여 작업을 의도한 어플리케이션에 package.json 파일을 생성. 뒤에 붙는 -y 명령어를 통해 디폴트 값으로 제공하는 기본 설정 값을 남겨둔다.

$ npm init -y

만일 뒤에 붙는 -y 명령어를 생략하게되면 다양한 내용들을 입력하도록 요구하는데(예시; 이름, 어플리케이션 버젼 등), 우선 엔터를 치면서 디폴트 내용을 저장하면 위 내용과 같은 결과가 나온다. 기본적인 디폴트 내용의 최종 내용은 다음 package.json 상에 기록되며, 추후에 언제든지 원하는 내용을 추가 및 수정할 수 있다. 가장 메인이 되는 파일의 명칭은 어떠한 내용이 되어도 상관이 없다.

// package.json
{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

다음으로 npm 명령어로 express를 설치한다. 배포용으로 쓰일 패키지임을 명시하는 package.json 파일 내 “dependency list”에 자동으로 Express항목과 version이 명시됨을 확인하자.

$ npm i express

Express를 일시적으로만 사용하고 배포용 dependency list에 저장하고 싶지 않는다면 아래의 명령어를 입력.

$ npm i express --no-save

dependencies가 아닌 로컬 개발환경에서 구동한다면(devDependencies) 아래의 명령어를 입력.

$ npm install express --save-dev






2. nodemon


✅ 개념 정의

Node에서는 코드에서 수정이 일어났을 때 코드의 수정 사항이 서버에 자동으로 반영되지 않는다. 즉, 코드를 수정하고나면 서버를 계속해서 재가동 해주어야 한다. 이를 보완하기 위해 nodemon 패키지를 이용한다.

✅ nodemon 설치 방법

  • npm 명령어를 이용하여 nodemon을 설치. git clone을 이용하여 설치할 수 있지만 보통은 패키지 관리를 위해 npm 명령어를 사용한 방법이 권장되는 편.
  • 끝에 g 를 붙임으로써 global 변수로 nodemon을 설치할 수 있다. 아래 명령어를 통해 nodemon 패키지를 system path 전역으로 설치할 수 있습니다. g 를 붙이지 않고 설치하는 local 설치와의 차이점은, local 설치는 node_modules 하위 디렉토리에 한정되어 설치가 이루어진다는 점이다.
  • 보통 npm package를 다운 받을 시 local / global 의 선택 기준으로, 대부분의 일반 패키지는 local로 설치 하게 되지만 CLI에서 실행 가능하고 프로젝트 전역에 걸쳐서 재사용이 되어야 하는 패키지는 global로 설치한다. 따라서 nodemon 설치는 global 설치가 권장되는 편이다.
$ npm install nodemon     # local dependency install
$ npm install -g nodemon  # global install
  • 이후 앞으로의 편의상 **package.json 내부의 npm script start 명령어 란에 아래와 같이 새롭게 nodemon을 경유하여 app.js를 실행한다는 의미의 명령어nodemon app.js를 추가한다. 이제 간단히 npm start** 명령어 만으로 언제든지 nodemon이 제공하는 도움을 받을 수 있다.
$ "scripts": {
    "start": "nodemon app.js"
  }
  • 필요시, 아래의 명령어를 이용하면 devDependency 로서 해당 내용을 설치 할 수 있다. 위 명령어와 아래 명령어의 차이점으로, package.json 내에서 해당 패키지가 dependency | devDependency 중 어디에 포함되어 적용되었는지를 확인.
$ npm install --save-dev nodemon  # local devDependency install
  • nodemon은 디렉토리(또는 디렉토리)를 계속 모니터링하고 변경 사항이 있으면 스크립트를 다시 시작한다. 수동으로 서버 종료 없이 재시작하는 방법은 실행중인 터미널 창에 rs 를 입력하는 것이다.
  • 더 자세한 사항은 공식문서를 참고하자. npm nodemon 공식문서






3. CORS 설정


✅ CORS란?

현재의 웹 브라우저는 보안상의 이유로 서로 다른 출처의 http 통신을 막도록 기본적으로 세팅되어 있다. 동일한 출처의 주체끼리만 서로 통신할 수 있도록 하는 이 SOP(Same Origin Policy) 정책은 보안성 향상을 위한 기본이다.

하지만 현실적으로 백엔드와 프론트 서버가 서로 다른 도메인에서 운용되는 현재의 3세대 웹 서비스 환경에서, 동일한 출처에서만 리소스를 주고 받을 수 없다. 따라서 이러한 SOP 정책을 올바르게 의도한 요청에 한해서 다소 완화시켜 서로간 통신을 가능케 해야 한다.

이는 별도의 CORS 설정을 통해 서로 다른 두개의 origin/domain 끼리의 데이터를 주고 받게 하기 위한 설정하여 이루어지며, 만일 해당 과정을 생략한다면 CORS 정책 위반을 이유로 웹 브라우저 차원에서 서버 통신을 막는다.

✅ 설치법

Cors 설정을 위한 npm 설치 CLI 명령어는 아래와 같습니다. 터미널에서 입력하여 설치를 진행한다.

$ npm install cors

✅ 다양한 사용법

✔️ 모든 request에 대해 CORS 요청을 설정하는 법

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

app.use(cors())

app.get('/ping', function (req, res, next) {
  res.json({message: 'pong'})
})

app.listen(3000, function () {
  console.log('server listening on port 3000')
})

✔️ 단 하나의 route에서만 CORS 요청을 설정하는 법

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

app.get('/ping', cors(), function (req, res, next) {
  res.json({message: 'pong'})
})

app.listen(3000, function () {
  console.log('server listening on port 3000')
})
  • 참고 사항으로, cors에서 기본값으로 설정된 값들은 아래와 같다. Cors와 관련하여 사용자의 요구에 맞게 다양하게 상세 설정을 변경할 수 있다. 다음의 공식문서를 보고 관련 내용을 확인할 수 있다.
{
  "origin": "*",
  "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
  "preflightContinue": false,
  "optionsSuccessStatus": 204
}






4. Dotenv 환경변수 관리


✅ 설치법

npm 패키지 매니저를 이용하여 dotenv 라이브러리를 Node.js 프로젝트에 설치한다.

$ npm install dotenv

✅ env 파일 작성

dotenv 라이브러리는 디폴트로 현재 디렉토리에 위치한 .env 파일로 부터 환경 변수를 읽어낸다. 따라서, .env 파일을 생성하고, 그 안에 필요한 환경 변수를 key-value 의 포멧으로 나열한다.

// .env
DB_HOST=localhost
DB_USER=root
DB_PASS=myPassword

이렇게 .env 파일에 저장해놓은 환경 변수들을 dotenv 라이브러리를 이용해서 process.env에 설정할 수 있는데, 자신의 프로젝트가 CommonJS 기반인지 ES 모듈 기반인지에 따라 라이브러리 사용법이 상이하므로 나눠서 분석해야 한다.

✅ CommonJS에서 환경 변수 불러오기 (require)

먼저 Node.js에서 전통적으로 제공해왔던 모듈 시스템인 CommonJS에서 dotenv 라이브러리를 어떻게 사용하는지 알아보자. 애플리케이션을 구동할 때 제일 먼저 실행되는 자바스크립트 파일(ex. app.jsindex.js)의 최상위에 다음과 같이 dotenv 라이브러리를 임포트한 후 config() 함수를 호출해주기만 하면 된다.

// app.js

require("dotenv").config();
console.log("DB_HOST:", process.env.DB_HOST);
console.log("DB_USER:", process.env.DB_USER);
console.log("DB_PASS:", process.env.DB_PASS);

예를 들어, 위 코드를 실행하면 process.env로 부터 읽어진 환경 변수가 출력되는 것을 볼 수 있다.

DB_HOST: localhost
DB_USER: root
DB_PASS: s1mpl3

하지만, 같은 파일 내에서 dotenv 라이브러리의 config() 함수를 호출하기 전에 process.env를 읽으면 안 되니 주의해야 한다. 그렇지 않다면 다음의 내용 처럼 ‘undefined’ 값이 반환된다.

// app.js

console.log("DB_HOST:", process.env.DB_HOST);
console.log("DB_USER:", process.env.DB_USER);
console.log("DB_PASS:", process.env.DB_PASS);

require("dotenv").config();
DB_HOST: undefined
DB_USER: undefined
DB_PASS: undefined

만약 .env가 아닌 다른 경로에 있는 파일에 환경 변수를 저장해놨다면 config() 함수를 호출 시 path 옵션을 넘기는 방법도 있다. 하지만 현재 프로젝트에서는 발생 가능한 다양한 에러 변수를 최소화하기 위해 .env 에 모든 환경 변수를 관리하도록 했다.

✅ ES 모듈에서 환경 변수 불러오기 (import)

require 대신에 import 키워드를 사용하는 ES 모듈에서는 dotenv 라이브러리를 어떤 방식으로 사용할까. ES 모듈을 사용할 때는 CommonJS를 사용할 때 보다 좀 더 주의가 필요가 있다. 아래 예시를 통해서 흔히 발생하는 문제를 확인할 수 있다.

아래 코드를 보면, dotenv 라이브러리를 제일 먼저 임포트하기 때문에 db.js 파일이 process.env에 접근할 때 환경 변수가 설정이 되어 있을 것 같다는 생각이 든다.

// db.js

export const db_host = process.env.DB_HOST;
export const db_user = process.env.DB_USER;
export const db_pass = process.env.DB_PASS;
// app.js

import dotenv from "dotenv";
import { db_host, db_user, db_pass } from "./db.js";

dotenv.config();

console.log("DB_HOST:", process.env.DB_HOST);
console.log("DB_USER:", process.env.DB_USER);
console.log("DB_PASS:", process.env.DB_PASS);

console.log({ db_host, db_user, db_pass });

하지만 실제 실행을 해보면 db.js 파일이 process.env에 접근했을 시점에는 환경 변수가 설정이 되어 있지 않았던 것을 알 수 있다.

DB_HOST: localhost
DB_USER: root
DB_PASS: s1mpl3
{ db_host: undefined, db_user: undefined, db_pass: undefined }

이러한 현상이 발생하는 이유는 dotenv.config() 함수가 db.js 파일이 임포트 된 이후 호출되었기 때문이다. 이 문제를 피하기 위해선 dotenv 라이브러리를 임포트하는 코드를 별도의 파일로 빼 그 속에 dotenv.config() 함수를 호출한다.

// env.js
import dotenv from "dotenv";
dotenv.config();
// app.js
import "./env.js";
import { db_host, db_user, db_pass } from "./db.js";

console.log("DB_HOST:", process.env.DB_HOST);
console.log("DB_USER:", process.env.DB_USER);
console.log("DB_PASS:", process.env.DB_PASS);

console.log({ db_host, db_user, db_pass });
DB_HOST: localhost
DB_USER: root
DB_PASS: s1mpl3
{ db_host: 'localhost', db_user: 'root', db_pass: 'myPassword' }






5. Morgan


✅ Morgan 이란?

NodeJS 서버로 구성된 웹 환경에서는 기본적으로 제공되어지는 로깅(네트워크 통신기록) 기능이 없기에, 로그(log)를 관리하기 위해서 외부의 서드파티 모듈/라이브러리를 사용할 것을 권장한다. 그 중 Morgan은 npm 에서 사용되는 로그 관리를 위한 여러 패키지 중 하나이며 많은 개발자들이 사용하고 있다.

Morgan을 사용하면 http(s) 통신시 프론트-백엔드간 소통시 필요로 하는 ‘기본 정보’들을 자동으로 포매팅하여 편리하게 주고 받을 수 있게 된다. 여기서 말하는 ‘기본 정보’란, http 통신시 request, response 형태로 주고 받는 status codehttp version 등의 메타 정보들을 뜻하며, node.js-express 선에서 제공하지 않는 이 기능을 외부의 패키지의 힘을 빌려 사용하게 된 것이다. 참고사항으로, Morgan을 사용할 때 내가 원하는 요소대로 내부 속성을 커스터마이징 하여 설정 할 수도 있다.

✅ 설치법

morgan을 설치.

$ npm install morgan

express 환경의 앱에서 morgan을 사용하도록 설정.

const express = require('express');
const logger = require('morgan'); // morgan 모듈 추가하기

const app = express();

app.listen(3000, () => { console.log('Running on port 3000');});

로그의 포맷을 아래와 같이 선택하거나 지정할 수 있습니다.

app.use(morgan('combined')); // morgan 사용하기

combined 로그 포맷을 통해 제공되어지는 기본 적인 로그 내용은 다음과 같습니다.

:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"

combined 외에도 다음 4가지의 다양한 포맷 설정이 가능합니다.

// common
[:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length]]

// dev
[:method :url :status :response-time ms - :res[content-length]]

// short
[:remote-addr :remote-user :method :url HTTP/:http-version :status :res[content-length] - :response-time ms]

// tiny
[:method :url :status :res[content-length] - :response-time ms]

참고링크: Morgan 공식문서 페이지


  • Node Express를 사용할 때 설정해야하는 다양한 npm 패키지(모듈)들을 설치 및 관리할 수 있다.
  • 사용하는 npm 패키지(모듈)들의 목적과 기능을 이해할 수 있습니다. 그리고 네트워크 통신시 개발자의 수고를 덜어주는 다음의 5가지의 기본 패키지를 이해하였습니다: [npm] express | nodemon | cors | dotenv | morgan.
profile
helloworld
post-custom-banner

0개의 댓글