요약
- Node Express를 사용 시 필요한 npm 패키지(모듈)들을 설치 및 관리할 수 있다
- npm 패키지(모듈)들의 목적과 기능.
- 네트워크 통신시 개발자의 수고를 덜어주는 5가지의 기본 패키지:
[npm] express | nodemon | cors | dotenv | morgan.
폴더 생성: mkdir myapp
폴더 진입: cd myapp
package.json파일 생성: npm init -y
package.json파일에서 "main" 파일을 app.js
로 수정
설치
$ npm install express
일시적으로만 사용하고 배포용 dependency list에 저장하고 싶지않다면
$ npm install express --no-save
로컬 개발환경에서 쓰고 싶은 패키지들을 관리하고 싶다면
$ npm install express --save-dev
디렉토리(또는 디렉토리)를 계속 모니터링하고 변경 사항이 있으면 스크립트를 다시 시작하는 패키지
- Node는 서버에 코드의 수정 사항이 자동으로 반영되지 않음.
설치
: node_modules 하위 디렉토리에 한정되어 설치
-g
: system path 전역에 설치 (권장)
$ npm install nodemon # local dependency install
$ npm install -g nodemon # global install
package.json 내부의 npm script start
명령어 란에 아래와 같이 새롭게 nodemon을 경유하여 app.js를 실행한다는 의미의 명령어(nodemon app.js)를 추가:
필요 시, devDependency 로 설치한다면
$ npm install --save-dev nodemon
수동으로 서버 종료 없이 재시작: rs
서버 종료: Ctrl
+ c
서로 다른 도메인에서 운용되는 백엔드/프론트 서버가 현재의 3세대 웹 서비스 환경에서 리소스를 주고 받을 수 있도록 SOP정책을 완화시켜주는 설정
SOP(Same Origin Policy) 정책
동일한 출처의 주체끼리만 서로 통신할 수 있도록 하는 정책
- 현재의 3세대 웹브라우저에서는 SOP정책에 따라 서로 다른 출처의 http 통신이 막혀있다
- 보안성 향상의 기본
CORS 설정
을 생략하면?
CORS 정책 위반으로 웹 브라우저 차원에서 서버 통신을 막는다!
설치
$ npm install cors
CORS 요청 설정하기
1. 모든 request에 대해
참고) 기본값
{
"origin": "*",
"methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
"preflightContinue": false,
"optionsSuccessStatus": 204
}
1. 설치
npm
패키지 매니저로 dotenv
라이브러리를 Node.js 프로젝트에 설치
$ npm install dotenv
2. env 파일 작성
dotenv
라이브러리는 기본값으로 현재 디렉토리에 위치한 .env
파일로부터 환경 변수를 읽어낸다
👉 .env
파일을 생성하고, 필요한 환경 변수를 key-value 형태로 나열한다.
.env 파일에 저장해놓은 환경 변수들을 dotenv 라이브러리를 이용해서 process.env
에 설정할 수 있다.
사용법 1. CommonJS에서 환경 변수 불러오기 (require)
애플리케이션을 구동 시, 제일 먼저 실행되는 자바스크립트 파일(ex. app.js, index.js)의 최상위에 dotenv 라이브러리를 임포트한 후 config() 함수
를 호출한다
app.js 실행 결과:
ㄴ process.env로 부터 읽어들인 환경 변수가 출력되는 것
dotenv 라이브러리의 config() 함수 호출 전에 process.env를 읽으면?
사용법 2. ES 모듈에서 환경 변수 불러오기 (import)
require 대신에 import 키워드를 사용
왜 undefined 일까?
- 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_HOST: localhost DB_USER: root DB_PASS: s1mpl3 { db_host: undefined, db_user: undefined, db_pass: undefined }
Solution
- 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;
- env.js 👉 dotenv를 별도 파일에서 import, config()함수 호출
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' }
npm
에서 사용되는 로그(log) 관리용 외부 서드파티 모듈/라이브러리
필요성: NodeJS 서버 기반 웹 환경에서는 로깅(네트워크 통신기록) 기능이 기본 제공되지 않으므로.
http(s) 통신시 프론트-백엔드간 소통시 필요로 하는 기본 정보
들을 자동으로 포매팅하여 편리하게 주고 받을 수 있다.
기본 정보
: http 통신시 request, response 형태로 주고 받는내부 속성을 커스터마이징 할 수 있다.
설치
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');});
로그의 포맷을 선택하거나 지정할 수 있다
ex)
app.use(morgan('combined')); // morgan 사용하기
로그 포맷 5가지
combined
[:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"]
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]
// app.js
const http = require("http");
const express = require("express");
const cors = require("cors");
const morgan = require("morgan");
const dotenv = require("dotenv");
const {appendFile} = require("fs")
// 핑퐁을 적극적으로 활용하기 위해 app의 express()메소드를 발동시킬 것이다
app = express();
//app.use는 수많은 패키지를 사용할 수 있게 하는 미들웨어이다
app.use(express.json());
app.use(cors());
app.use(morgan('combined')); // 로깅 패키지 | 옵션: dev, tiny, combined
// dotenv.config(): 환경변수를 활용할 수 있게 하는 메서드
dotenv.config()
// /ping 이라는 타겟 리소스에 요청이 들어오면 pong을 보낸다는 메시지
// health check
app.get("/ping", (req,res) => {
res.json({ message : "pong" });
})
// 위에 선언한 http로 서버를 열어주어야 한다
const server = http.createServer(app);
//dotenv의 환경변수로 저장된 포트번호를 불러올 것이다
const PORT = process.env.PORT;
const start = async () => {
// 포트번호에 맞게 서버를 잘 동작시켜 모든 것들을 서버로서 계속 듣고 있겠다
server.listen(PORT, () => console.log(`Server is listening on ${PORT}`));
}
// start를 실행하겠다
start();
👉 실행 결과
package.json에 "start": "nodemon app.js"
가 잘 입력되어 있기 때문에
npm start 명령어 실행 시 다음과 같이 [nodemon]에 대해 잘 실행된다
하지만 서버에서 PORT번호가 undefined로 process.env.PORT
에서 못가져오는 것을 알 수 있음! 이것을 해결하려면 숨김파일 3개를 생성해야 한다.
.gitignore
: 깃허브 상에 내가 만든 파일이 올라가지 않도록 숨김처리.env.sample
: 환경변수를 누구에게나 보여줄 수 있는 파일.env
: 실제 환경변수를 저장할 파일ls -al
명령어로 숨김파일도 다 잘 생성됐는지 확인:
데이터 입력하기:
.gitignore
: 실제환경변수 파일(.env), 불필요한 대량의 파일들(node_modules/).env.sample
: 깃허브에 올려서 다른 개발자가 보고 이해할 수 있는 모조값.env
: 내가 실제 적용할 포트 번호nodemon 기능 활용: cmd
누르고 rs 입력. 서버를 끄지 않고 재실행한다
👉 .env
에 입력한 포트 번호 3000을 잘 읽어와 서버에 반영된 것을 확인!
get요청 👉 pong 확인!
morgan() 로깅 옵션에 따른 결과 확인: tiny와 dev는 형태가 유사함
app.use(express.json());
"난해하게 들어올 수 있었던 데이터구조를 개발자들이 가독성 좋게 구분지어서 깔끔하게 구조화하고 정리해서 터미널이나 코드 화면단에 보여질 수 있게 하는게 express.json()메소드가 가진 숨김기능 중 하나이다
옛날: app.use(bodyParser.json())이라는 별도의 메소드를 써야 했다
express.json이 들어서면서 deprecated됐음(더이상 서비스 제공하지 않음)"
특정 api endpoint에만 동작할 수 있도록 cors()를 설정한다면?
👉 app.use(cors())는 주석처리하고, 특정 app.get()의 매개변수로 cors()를 입력하여 다양하게 처리할 수 있다
끝으로..
공식문서를 찾아가며 자신만의 철학을 담아 딥하게 커스터마이징 하자
nodejs는 런타임 환경을 제공
expressjs는 직접적인 웹서비스 기능을 담당