본문으로 바로가기

 

바닐라 node에 대한 지식이 전무했을 때 적은 express 관련 글이다. 한 번 훑고 express를 공부해보자.

 

 

Express에서 간단한 server 만들기

var express = require("express"); var app = express(); PORT = 4000; const handleListening = () => { console.log(`Listening on: http://localhost:${PORT}`); }; app.listen(PORT, handleListening); requi..

darrengwon.tistory.com


 express-generator

 

노마드 코더에서 youtube-clone에서는 다음과 같이 기본 폴더 구조를 생성했다.

controllers에서 서버 로직을 짜고 (req, res) => ...

models에서 DB 구조를 짰으며

routers에서 라우팅을 처리하고

views에서 렌더링할 pug 또는 ejs를 저장하였다.

 

이렇게 폴더의 구조를 직접 만들어 할 수도 있지만 필요한 패키지와 기본 폴더 구조까지 만들어 주는 express-generator라는 패키지를 이용해보자.

npm i -g express-generator

express-generator를 전역 설치했으므로 명령창에 express를 입력할 수 있게 되었다.

express learn-express --view=pug

learn-express라는 폴더 이름 아래에 views, routes, public 등이 만들어지고 템플릿 엔진은 pug로 설정합니다. 물론 ejs를 선호하는 분도 계시고 저도 그렇지만 진행합니다.

 

 

 

여담으로, express-generator는 기본 폴더 구조를 살펴보기 위함이니 남용하지 말고 직접 파일을 만들어서 관리하는 게 속도 편하고 관리하기에도 편합니다.

 

 

오른쪽은 express generator로 생성된 파일 구조입니다.

package-lock.json이나 node_modules이 없으므로 npm init후 여러 패키지를 설치해봅시다.

npm init

시작 후에는 express generator가 만든 dependencies를 설치하기 위해 npm install을 진행합시다.

npm i

 

중앙 통제실 app.js

여기서 npm start를 입력하면 package.json에 설정한 대로 실행이 됩니다. express generator의 기본 포트는 3000번 입니다. 그런데 bin/www에서 실행되는 서버 로직을 살펴보면 app.js입니다.

createServer((req, res) => res.send(`<h1>hello</h1>`)) 따위를 적곤 했는데...

생각해보면 그동안 express를 사용할 때 관습처럼 app.js를 생성한 후 모듈로 export 했습니다.

import express from "express"
const app = express();
...
app.get("/", (req, res) => res.send(console.log(`<h1>hello</h1>`)))
...
export default app;

 

app.js는 중앙 통제실이라고 생각하면 됩니다. (미들웨어를 포함한) 라우터를 조립하는 공간입니다. 대체적으로 app.js는 다음과 같은 순서로 작성됩니다.

 

 

미들웨어와 use(), next()

노마드 코더에서 다음과 같이 미들웨어를 설치하여 운용한 경험이 있을 겁니다.

// middleware
app.use(helmet());
app.set("view engine", "pug"); //미들웨어가 아니다. express 설정이다.
app.use(cookiePaser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(morgan("dev"));

 

여기서 눈여겨 볼 것은 app.get, app.post와 같이 http 메소드가 아닌 use와 set이 사용되었다는 것입니다.

set은 익스프레스 설정, 값 저장을 의미하고 use는 미들 웨어 장착 및 사용을 의미합니다. 여기서 주의할 점은 라우터도 미들웨어라는 것입니다. use가 사용되었다면 미들웨어라고 생각합시다.

// 라우터도 미들웨어다!
app.use(routes.home, globalRouter);
app.use(routes.users, userRouter);
app.use(routes.videos, videoRouter);
 

Router, export, import

간단한 export, import와 express의 Router 메소드를 알아보자. export default는 한 파일을 통째로 export할 수도 있고 특정 함수만을 export할 때도 사용할 수도 있다. export default app import app from "./a..

darrengwon.tistory.com

 

한편, 미들웨어는 req와 res 사이에서 작동하기 때문에 요청과 응답을 제어할 수 있다.

 

app.js에 다음 내용을 추가하고 로컬 호스트로 접근해보면 콘솔에 다음 내용이 출력되는 것을 볼 수 있다. 여기서 눈여겨볼 점은 인자에 next가 있고 다음 미들웨어로 넘어가기 위해 next()를 적었다는 것이다. 두번째 미들웨어에서는 next()를 호출하지 않았기 때문에 다음으로 넘어가지 않는다. 이를 이용해 특정 미들웨어까지만 진행하게 만들기도 한다.

 

app.use((req, res, next) => {
  console.log("내가 만든 미들웨어");
  if (+new Date() % 2 === 0) {
    next();
  } else {
    res.send("당첨"); //next()가 없으므로 여기서 끝난다.
  }
});

 

생각해보면 app.get 이나 app.post에는 next()를 호출한 적이 없을 것이다. 이는 메소드를 처리하면 더 이상 다음으로 넘어갈 일이 없기 때문이다.

 

한편, 유용하고 자주 쓰이는 미들웨어가 있으니 개발 시에 설치하고 app.js에 세팅하자. 미들웨어는 예전에 다룬 적이 있으니 첨부한다.

 

morgan, body-parser(4.16.0부터 express 내장), cookie-parser, express-session, flash, helmet, passport 등

 

 

Middleware

미들웨어는 req와 최종 res 사이에 존재하는 중간 단계로 로그 기록, 보안 절차 등의 역할을 수행한다. 간단하게 미들웨어를 만들어보자 import express from "express"; const app = express(); const PORT = 400..

darrengwon.tistory.com

기본적으로 다음과 같이 설정한다.

app.use(helmet());
app.use(logger("dev"));
app.use(express.static(path.join(__dirname, "public")));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookiePaser("secret code"));
app.use(
  session({
    resave: false, //세션 객체에 수정 사항이 없어도 저장합니까?
    saveUninitialized: false, //처음 빈 세션 객체를 저장합니까?
    secret: "secret code", // cookieParser의 인자와 같은 값이어야 함
    cookie: {
      httpOnly: true,
      secure: false
    }
  })
);
app.use(flash());

 

 

404 not found와 에러처리

 

 

404 NOT Found, Error 처리 미들웨어

라우터를 다 찾았는데도 요청한 내용이 없다면 서버가 죽는다. 때문에 404를 처리하는 미들웨어(라우터)를 만들어야 한다. (이 포스팅의 주제와는 관련 없지만 기억하자. 라우터도 미들웨어다!) 일반적인 app.js의..

darrengwon.tistory.com

 

 


darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체