본문 바로가기

WINK-(Web & App)/Express.js (Node.js) 스터디

[2024 여름방학 Node.js 스터디] 김지나 #4주차

반응형

5장. 패키지 매니저

 

5.1. npm 알아보기

- npm: 노드 패키지 매니저 

- 패키지: npm에 업로드된 노드 모듈

- 자바스크립트 프로그램은 패키지로 npm에 등록되어 있으므로 필요에 따라 설치해서 사용하면 됨

 

5.2. package.json으로 패키지 관리하기

- package.json: 설치한 패키지의 버전을 관리하는 파일

- 노드 프로젝트를 시작하기 전에는 폴더 내부에 package.json부터 만들고 시작해야 함!!

package name 패키지의 이름
version 패키지의 버전
entry point 자바스크립트 실행 파일 진입점
test command 코드를 테스트할 때 입력할 명령어를 의미
git repository 코드를 저장해둔 깃(Git) 저장소 주소를 의미
keywords 패키지를 쉽게 찾을 수 있게 함
license 해당 패키지의 라이선스를 넣음

 

5.3. 패키지 버전 이해하기

- 노드 패키지들의 버전은 항상 세 자리로 이뤄져있음

- 첫 번째: 메이저 버전(0: 초기 개발, 1: 정식 버전), 하위 호환이 안 될 정도로 패키지의 내용이 수정되었을 때

- 두 번째: 마이너 버전, 하위 호환이 되는 기능 업데이트할 때 

- 세 번째: 패치 버전, 기존 기능의 문제를 수정했을 때

- ^: 마이너 버전까지만 설치 또는 업데이트

- ~: 패치 버전까지만 설치 또는 업데이트

 

5.4. 기타 npm 명령어 

npm update [패키지 이름] 업데이트 가능한 모든 패키지가 Wanted에 적힌 버전으로 업데이트 됨
npm uninstall [패키지 이름] 해당 패키지를 제거하는 명령어
npm search [검색어] npm의 패키지를 검색할 수 있음
npm info [패키지 이름] 패키지의 세부 정보를 파악하고자 할 때 사용하는 명령어
npm login npm 로그인을 위한 명령어
npm whoami 로그인한 사용자가 누구인지 알림
npm logout npm login으로 로그인한 계정을 로그아웃할 때 사용
npm version [버전] 명령어를 사용하면 package.json의 버전을 올림
npm deprecate [패키지 이름] [버전] [메시지] 해당 패키지를 설치할 때 경고 메시지를 띄우게 하는 명령어
npm publish 자신이 만든 패키지를 배포할 때 사용
npm unpublish 배포한 패키지를 제거할 때 사용

 

6장. 익스프레스 웹 서버 만들기

 

6.1. 익스프레스 프로젝트 시작하기

{
  "name": "learn-express",
  "version": "0.0.1",
  "description": "익스프레스를 배우자",
  "main": "app.js",
  "scripts": {
    "start": "nodemon app"
  },
  "author": "ZeroCho",
  "license": "MIT"
}

- package.json 만들기

//app.js
const express = require('express');

const app = express();
app.set('port', process.env.PORT || 3000);

app.get('/', (req, res) => {
  res.send('Hello, Express');
});

app.listen(app.get('port'), () => {
  console.log(app.get('port'), '번 포트에서 대기 중');
});

- 익스프레스 내부에 http 모듈이 내장되어 있어서 서버의 역할을 할 수 있음

- app.set('port', 포트)로 서버가 실행될 포트 설정

- app.set(키, 값): 데이터 저장

- app.get(키): 데이터 가져오기

 

6.2. 자주 사용하는 미들웨어

- 미들웨어: 요청과 응답의 중간에 위치, 요청과 응답을 조작해 기능을 추가하고 나쁜 요청을 걸러냄

- app.use(미들웨어) 꼴로 사용됨

// app.js
...
app.set('port', process.env.PORT || 3000);

app.use((req, res, next) => {
  console.log('모든 요청에 다 실행됩니다.');
  next();
});
app.get('/', (req, res, next) => {
  console.log('GET / 요청에서만 실행됩니다.');
  next();
}, (req, res) => {
  throw new Error('에러는 에러 처리 미들웨어로 갑니다.')
});

app.use((err, req, res, next) => {
  console.error(err);
  res.status(500).send(err.message);
});

app.listen(app.get('port'), () => {
...

- 미들웨어는 위에서부터 아래로 순서대로 실행되며 요청과 응답 사이에 기능을 추가할 수 있음

- next: 다음 미들웨어로 넘어가는 함수

app.use(미들웨어) 모든 요청에서 미들웨어 실행
app.use('/abc', 미들웨어) abc로 시작하는 요청에서 미들웨어 실행
app.post('/abc', 미들웨어) abc로 시작하는 POST 요청에서 미들웨어 실행

 

6.2.1. morgan

- 기존 로그 외에 추가적인 로그를 볼 수 있음

 app.use(morgan('dev'));

 

6.2.2. static

- 정적인 파일들을 제공하는 라우터 역할

 app.use('요청 경로', express.static('실제 경로'));

 

6.2.3. body-parser

- 요청의 본문에 있는 데이터를 해석해서 req.body 객체로 만들어주는 미들웨어

app.use(express.json());
app.use(express.urlencoded({ extended: false }));

 

6.2.4. cookie-parser

- 요청에 동봉된 쿠키를 해석해 req.cookies 객체로 만들어줌

app.use(cookieParser(비밀 키));

 

6.2.5. express-session

- 세션 관리용 미들웨어

- 특정 사용자를 위한 데이터를 임시적으로 저장해둘때

 

6.2.6. 미들웨어의 특성 활용하기

- 미들웨어의 특성

1) req, res, next를 매개변수로 갖는 함수로서 app.use나 app.get, app.post 등으로 장착한다

2) 특정한 주소의 요청에만 미들웨어가 실행되게 하려면 첫 번째 인수로 주소를 넣으면 됨

3) 동시에 여러 개 미들웨어 장착 가능

4) 다음 미들웨어로 넘어가려면 next 함수 호출

5) 정적 파일을 제공할 때 특정 미들웨어는 실행되지 않음

6) 장착 순서에 따라 어떤 미들웨어는 실행되지 않을 수도 있음

7) res.locals 객체를 통해 미들웨어 간의 데이터 공유 가능

 

6.2.7. multer

- 이미지, 동영상 등을 비롯한 여러 가지 파일을 멀티파트 형식으로 업로드 할 때 사용하는 미들웨어

- 멀티파트 형식: enctype이 multipart/form-data인 폼을 통해 업로드하는 데이터의 형식

 

6.3. Router 객체로 라우팅 분리하기

 

- 라우터를 분리할 수 있는 방법

1) routes 폴더를 만들고 그 안에 index.j와 user.js를 작성

//index.js
const express = require('express');

const router = express.Router();

// GET / 라우터
router.get('/', (req, res) => {
  res.send('Hello, Express');
});

module.exports = router;
//user.js
const express = require('express');

const router = express.Router();

// GET /user 라우터
router.get('/', (req, res) => {
  res.send('Hello, User');
});

module.exports = router;
...
const path = require('path');

dotenv.config();
const indexRouter = require('./routes');
const userRouter = require('./routes/user');
...
  name: 'session-cookie',
}));

app.use('/', indexRouter);
app.use('/user', userRouter);

app.use((req, res, next) => {
  res.status(404).send('Not Found');
});

app.use((err, req, res, next) => {
...

 

2) app.use를 통해 app.js에 연결

3) 에러 처리 미들웨어 위에 404 상태 코드를 응답하는 미들웨어 하나 추가

4) 서버를 실행하고 localhost:3000, localhost:3000/user로 접속하면 응답을 받을 수 있음

 

6.4. req, res 객체 살펴보기

req.app req 객체를 통해 app 객체에 접근
req.body body-parser 미들웨어가 만드는 요청의 본문을 해석
 req.cookies cookie-parser 미들웨어가 만드는 요청의 쿠키를 해석
req.ip 요청의 ip 주소가 담겨 있음
req.params 라우트 매개변수에 대한 정보가 담긴 객체
req.query 쿼리스트링에 대한 정보가 담긴 객체
req.signedCookies 서명된 쿠키들은 req.cookies 대신 여기에 담겨있음
req.get(헤더 이름) 헤더의 값을 가져오고 싶을 때 사용

- req 객체

res.app res 객체를 통해 app 객체에 접근 가능
res.cookie(키, 값, 옵션) 쿠키를 설정하는 메서드
res.clearCookie(키, 값, 옵션) 쿠키를 제거하는 메서드
res.end() 데이터 없이 응답을 보냄
res.json(JSON) JSON 형식의 응답을 보냄
res.locals 하나의 요청 안에서 미들웨어 간에 데이터를 전달하고 싶을 때 사용하는 객체
res.redirect(주소) 리다이렉트할 주소와 함께 응답을 보냄
res.render(뷰, 데이터) 템플릿 엔진을 렌더링해서 응답할 때 사용
res.send(데이터) 데이터와 함께 응답을 보냄
res.sendFile(경로) 경로에 위치한 파일을 응답함
res.set(헤더, 값) 응답의 헤더를 설정
res.status(코드) 응답 시의 HTTP 상태 코드를 지정

- res 객체

 

6.5. 템플릿 엔진 사용하기

- 자바스크립트를 사용해서 HTML을 렌더링할 수 있게 함

 

6.5.1. 퍼그(제이드)

- 문법이 간단해서 코드양이 줄어든다는 장점이 있음

 

6.5.1.1. HTML 표현

퍼그 HTML
doctype html
html
    head
        title = title
        link(rel='stylesheet', href='/stylesheets/style.css')
<!DOCTYPE html>
<html>
    <head>
        <title>익스프레스</title>
        <link rel="stylesheet" href="/style.css"/>
    </head>
</html>
퍼그 HTML
#login-button
.post-image
span#highlight
p.hidden.full
<div id="login-button></div>
<div class="post-image"></div>
<span id="highlight"></span>
<p class="hidden full"></p>

 

퍼그 HTML
p Welcome to Express
button(type='submit') 전송
<p> Welcome to Express </p>
<button type="submit">전송</button>

- 여러 줄을 입력하고 싶으면 파이프 (|) 넣기

- style, script 태그로 CSS 또는 자바스크립트 코드를 작성하고 싶다면 태그 뒤에 점을 붙임

 

6.5.1.2. 변수

- 자바스크립트 변수를 템플릿에 렌더링 가능

 

6.5.1.3. 반복문

- 반복문을 사용할 수 있으며 반복 가능한 변수인 경우에만 해당됨

 

6.5.1.4. 조건문

- 조건문을 사용할 수 있으며 if, else if, else를 사용할 수 있음

 

6.5.1.5. include

- 다른 퍼그나 HTML을 넣을 수 있음

 

6.5.1.6. extends와 block

- 레이아웃을 정할 수 있으며 공통 레이아웃 부분을 따로 관리할 수 있음

 

6.5.2. 넌적스

- HTML 문법을 그대로 사용하되 추가로 자바스크립트 문법을 사용할 수 있음

 

6.5.2.1. 변수

- res.render 호출 시 보내는 변수를 넌적스가 처리함

- 변수는 {{ }}로 감쌈

 

6.5.2.2. 반복문

- {% %} 안에 반복문 사용 가능

- 반복문에서 인덱스를 사용하고 싶다면 loop.index라는 특수한 변수 사용 가능

 

6.5.2.3. 조건문

- 조건문은 {% if 변수 %}. {% elif %}, {% else %}, {% endif %}로 이뤄져 있음

 

6.5.2.4. include

- 다른 HTML 파일을 넣을 수 있음

 

6.5.2.5. extends와 block

- 레이아웃을 정할 수 있으며 공통 레이아웃을 따로 관리할 수 있음

 

6.5.3. 에러 처리 미들웨어

- 에러 처리 미들웨어는 error라는 템플릿 파일을 렌더링함

- 렌더링 시 res.locals.message와 res.locals.error에 넣어준 값을 함께 렌더링함

 

반응형