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 |
퍼그 | HTML |
p Welcome to Express button(type='submit') 전송 |
- 여러 줄을 입력하고 싶으면 파이프 (|) 넣기
- 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에 넣어준 값을 함께 렌더링함
'WINK-(Web & App) > Express.js (Node.js) 스터디' 카테고리의 다른 글
[2024-2 Node.js 스터디] 김민재 #1주차 (0) | 2024.10.06 |
---|---|
[2024 여름방학 Node.js 스터디] 백채린 #4주차 5~6장 (0) | 2024.08.15 |
[2024 여름방학 Node.js 스터디] 이종윤 #4주차 (0) | 2024.08.12 |
[2024 여름방학 Node.js 스터디] 이종윤 #3주차 (0) | 2024.08.02 |
[2024 여름방학 Node.js 스터디] 백채린 #3주차 4장 (0) | 2024.08.01 |