상권's
TIL 20 (express.js, 미들웨어, 디버깅, location header)(2021.10.26) 본문
-2021.10.26 오늘의 코플릿-
부분적으로 오름차순 정렬*된 정수의 배열(rotated)과 정수(target)를 입력받아 target의 인덱스를 리턴해야 합니다.
부분적으로 정렬된 배열: 배열을 왼쪽 혹은 오른쪽으로 0칸 이상 순환 이동할 경우 완전히 정렬되는 배열
예시: [4, 5, 6, 0, 1, 2, 3]은 왼쪽으로 3칸 또는 오른쪽으로 4칸 순환 이동할 경우 완전히 정렬됩니다.
// return rotated.indexOf(target) 시간복잡도 O(n)
// 중간을 자른다. parseInt(rotated.length / 2)
// 앞 서 학습했던 이진트리탐색을 이용해보자.
첫 수도코드 => 단순히 indexOf를 사용할 경우 시간 복잡도가 O(n)이 나오는데, 해당 문제에서는 O(logN) 로 구현하라고 했습니다. 그래서 앞서 이진탐색트리를 이용해서 해당 문제를 풀어보려고 했지만, 정확한 구현이 어려워서 레프런스를 통해서 문제의 풀이 방법을 학습해보겠습니다.
const rotatedArraySearch = function (rotated, target) {
let front = 0;
let back = rotated.length - 1 // 앞서 학습했던 이진탐색처럼 설정한다.
while(front <= back) { // 탈출 조건
let middle = parseInt((front + back) / 2) // 배열의 중간 인덱스를 찾는다.
if(rotated[middle] === target) { // 중간 요소가 target이랑 같으면 인덱스를 리턴한다.
return middle
} // 그러지 않다면..
if( rotated[front] < rotated[middle]) { // 중간의 요소가 맨 앞의 요소보다 크다면 (미들 요소는 큰 요소들 축에 속한다.)
if ( target < rotated[middle] && rotated[front] <= target) { //여기서 타겟이 미들보다 작고, 타겟이 앞의 요소보다 크다면,
back = middle - 1 // front 와 middle 사이에 타겟이 있기 때문에 back을 middle보다 하나 앞으로 옮긴다. 프론트는 그대로 0번째
}
else {
front = middle + 1 // 그게 아니라면 front를 미들+1로 만들어준다. back은 그대로 마지막 요소
}
}
else { // rotated[front] > rotated[middle]
if ( target <= rotated[back] && rotated[middle] < target) { // 미들의 요소보다 타겟이 더 크고, back의 요소보다 작다면 => 타겟은 미들 뒤쪽에 있다.
front = middle + 1 // front를 미들에 1을 더한 값으로, 미들 뒤쪽을 살펴본다. back은 그대로 마지막 요소
}
else {
back = middle - 1 // 그게 아니라면 back을 middle 앞의 숫자로 만들어 준다.
}
}
}
return -1
};
레프런스 => 미들보다 taget이 큰 경우에는 미들의 뒤쪽을 살펴보고, 미들이 target보다 큰 경우에는 미들의 앞 쪽을 살펴봅니다. slice를 이용하게 되면 시간복잡도가 올라갑니다. 그래서 기존에 있는 배열을 그대로 이용을 하면서, target이 있는 범위를 찾아서 점점 좁혀가면서 찾는 방법입니다.
=> 미들 값을 찾고 좁혀 나가는 부분에 대해서는 구현을 했지만, 경우의 수에 대해서 구현하는 것이 쉽지 않았지만 혼자의 힘으로 결과물을 보지 못한 점에 대해서 크게 아쉽습니다.
지속적으로 코드를 살펴보고 다시 구현해봄으로써 이해한 것을 활용할 수 있도록 노력해야겠습니다.
지난 주부터 node.js를 통해서 http 트랜젝션, express.js에 대해서 학습했습니다.
항공편 조회/ 예약에 관한 클라이언트 요청이 들어오면 찾는 내용을 리턴해주는 서버를 구현해봤습니다.
항공편 조회/ 변경
// [GET] /flight
// 요청 된 departure_times, arrival_times, destination, departure 값과 동일한 값을 가진 항공편 데이터를 조회합니다.
findAll: (req, res) => {
if (req.query.departure_times !== undefined && req.query.arrival_times === undefined) {
// 출발 시간은 입력이 되었지만, 도착 시간이 입력이 되지 않으면...
const list = flights.filter((item) => { // 출발 시간이 동일한 모든 비행기를 조회한다.
return item.departure_times === req.query.departure_times
});
return res.status(200).json(list);
}
else if (req.query.departure_times === undefined && req.query.arrival_times !== undefined) {
// 출발 시간이 입력되지 않고, 도착시간만 입력될 경우
const list = flights.filter((item) => { // 도착시간이 동일한 모든 비행기를 조회한다.
return item.arrival_times === req.query.arrival_times
});
return res.status(200).json(list);
}
else if (req.query.departure_times !== undefined && req.query.arrival_times !== undefined) {
// 출발 시간, 도착 시간 둘 다 입력될 경우
const list = flights.filter((item) => { // 해당 시간들과 동일한 모든 비행기를 조회한다.
return item.departure_times === req.query.departure_times && item.arrival_times === req.query.arrival_times
});
return res.status(200).json(list);
}
else if (req.query.departure !== undefined && req.query.destination !== undefined) {
// 출발지와 도착지가 입력되었다면,
const list = flights.filter((item) => { // 해당 결과와 동일한 모든 비행기를 조회한다.
return item.departure === req.query.departure.toUpperCase() && item.destination === req.query.destination.toUpperCase()
})
return res.status(200).json(list);
}
else if (req.query.departure !== undefined && req.query.destination === undefined) {
// 출발지는 입력이 되었고, 도착지가 입력되지 않았을 경우
const list = flights.filter((item) => { // 출발지가 동일한 모든 비행기를 조회한다.
return item.departure === req.query.departure.toUpperCase()
})
return res.status(200).json(list);
}
else if (req.query.departure === undefined && req.query.destination !== undefined) {
// 출발지는 입력이 안되고 도착지만 입력이 되었을 경우,
const list = flights.filter((item) => { // 도착지가 동일한 모든 비행기를 조회한다.
return item.destination === req.query.destination.toUpperCase()
})
return res.status(200).json(list);
}
res.json(flights); // 아무거도 입력이 안 될 경우, 모든 비행기를 조회한다.
},
// [GET] /flight/:id
// 요청 된 id 값과 동일한 uuid 값을 가진 항공편 데이터를 조회합니다.
findById: (req, res) => {
if (req.params.id !== undefined) {
// 입력된 id 값과 동일한 비행기 코드(uuid) 를 조회한다.
const list = flights.filter((item) => {
return item.uuid === req.params.id
})
return res.status(200).json(list);
}
res.json(flights); // 모든 비행기를 조회한다.
},
// [PUT] /flight/:id 요청을 수행합니다.
// 요청 된 id 값과 동일한 uuid 값을 가진 항공편 데이터를 요쳥 된 Body 데이터로 수정합니다.
update: (req, res) => {
let data;
// TODO:
if (req.params.id !== undefined) { // 입력된 값과 동일한 비행기를 찾는다.
data = flights.filter((item) => {
return item.uuid === req.params.id
}) // 해당 비행기의 내용을 수정한다.
for (let n = 0; n < data.length; n++) {
data[n].arrival_times = req.body.arrival_times
data[n].departure = req.body.departure
data[n].departure_times = req.body.departure_times
data[n].destination = req.body.destination
} // test에서는 하나의 항공편만 조회가 되는데 만약 다수의 항공편이 입력된다면
// for 문이나 map을 이용할 수 있을 듯한데.. map은 구현이 잘 되지 않아서 추가적인 학습이 필요할 거 같다.
return res.status(200).json(...data);
}
}
항공편 예약
// [GET] /book 요청을 수행합니다.
// 전체 데이터 혹은 요청 된 flight_uuid, phone 값과 동일한 예약 데이터를 조회합니다.
findById: (req, res) => {
// 조회를 할 때, 비행기 코드나 번호로 가능하다.
if (req.query.flight_uuid !== undefined) {
// 비행기 코드가 입력이 된다면,
const list = booking.filter((item) => {
return item.flight_uuid === req.query.flight_uuid
}) // 해당 코드와 맞는 예약을 찾는다.
return res.status(200).json(list);
}
else if (req.query.phone !== undefined) {
// 번호가 입력된다면,
const list = booking.filter((item) => {
return item.phone === req.query.phone
}) // 해당 번호와 맞는 예약을 찾는다.
return res.status(200).json(...list);
}
return res.status(200).json(booking); // 아니면 모든 예약내역을 출력한다. => 서비스를 구현한다면, 해당 부분은 login시 사용했던,
// 아이디를 기준으로 찾으면 좋을 듯 하다.
},
// [POST] /book 요청을 수행합니다.
// 요청 된 예약 데이터를 저장합니다.
// 응답으로는 book_id를 리턴합니다.
// Location Header로 예약 아이디를 함께 보내준다면 RESTful한 응답에 더욱 적합합니다.
create: (req, res) => {
// TODO:
// 예약을 진행한다.
let book = req.body
booking.push(book)
let id = booking.length + '-' + req.body.name + '-' + req.body.phone // 예약에 따른 고유번호를 만들어준다.
res.location(`/book/${flight_uuid}`) // 이를 통해서 locaiton header에 예약 정보를 확인할 수 있는 링크를 담을 수 있습니다.
return res.status(201).json({예약정보 : id}) // 예약 정보가 담겨있는 정보를 넘겨준다. "예약정보": "1-sangkwon-010-5328-2406" 이렇게 출력이 될 것으로 예상됨
},
// [DELETE] /book?phone={phone} 요청을 수행합니다.
// 요청 된 phone 값과 동일한 예약 데이터를 삭제합니다.
deleteById: (req, res) => {
// 번호를 입력해서 예약을 삭제한다.
if (req.query.phone !== undefined) {
let list = booking.filter((item) => {
return item.phone !== req.query.phone
})
booking = list
}
return res.status(200).json(booking);
}
EXPRESS.JS 공식문서를 통해서 APP.JS를 만들고 학습해보기 출처
// express 시작하기
// 폴더를 하나 만든 후, 해당 폴더 터미널 => npm init
// App.js 파일을 하나 만든다.
// npm install express => express를 다운 받는다.
// 아래와 같이 입력하면 실행할 수 있다.
const express = require('express')
const app = express()
const port = 3000
// 기본 라우팅
// 라우팅은 URI(또는 경로) 및 특정한 HTTP 요청 메소드(GET, POST 등)인 특정 엔드포인트에 대한 클라이언트 요청에 애플리케이션이 응답하는 방법을 결정하는 것을 말합니다.
// 각 라우트는 하나 이상의 핸들러 함수를 가질 수 있으며, 이러한 함수는 라우트가 일치할 때 실행됩니다.
// 라우트 정의에는 다음과 같은 구조가 필요합니다.
// app.METHOD(PATH, HANDLER)
// app은 express의 인스턴스입니다.
// METHOD는 HTTP 요청 메소드입니다.
// PATH는 서버에서의 경로입니다.
// HANDLER는 라우트가 일치할 때 실행되는 함수입니다.
// Express에서 정적 파일 제공
// 이미지, CSS 파일 및 JavaScript 파일과 같은 정적 파일을 제공하려면 Express의 기본 제공 미들웨어 함수인 express.static을 사용하십시오.
// 정적 자산이 포함된 디렉토리의 이름을 express.static 미들웨어 함수에 전달하면 파일의 직접적인 제공을 시작할 수 있습니다. 예를 들면,
//다음과 같은 코드를 이용하여 public이라는 이름의 디렉토리에 포함된 이미지, CSS 파일 및 JavaScript 파일을 제공하십시오.
// app.use(express.static('public'));
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
// node app.js 로 실행할 수 있다.
라우팅: 메소드와 URL에 따라 분기(Routing)하기
메소드와 URL(/lower, /upper 등)로 분기점을 만드는 것을 라우팅(Routing)이라고 합니다.
클라이언트는 특정한 HTTP 요청 메소드(GET, POST 등)나 서버의 특정 URI(또는 경로)로 HTTP 요청을 보냅니다. 라우팅은 클라이언트의 요청에 해당하는 메소드와 Endpoint에 따라 서버가 응답하는 방법을 결정하는 것입니다.
app.get('/', (req, res) => {
res.send('Hello World!')
})
get의 내부에 있는 콜백함수를 통해서 요청과 응답을 처리할 수 있습니다. 아래와 같은 메소드를 통해서 클라이언트에게 응답을 전송할 수 있습니다.
응답 메소드
다음 표에 표시된 응답 오브젝트에 대한 메소드(res)는 응답을 클라이언트로 전송하고 요청-응답 주기를 종료할 수 있습니다. 라우트 핸들러로부터 다음 메소드 중 어느 하나도 호출되지 않는 경우, 클라이언트 요청은 정지된 채로 방치됩니다.
res.download() | 파일이 다운로드되도록 프롬프트합니다. |
res.end() | 응답 프로세스를 종료합니다. |
res.json() | JSON 응답을 전송합니다. |
res.jsonp() | JSONP 지원을 통해 JSON 응답을 전송합니다. |
res.redirect() | 요청의 경로를 재지정합니다. |
res.render() | 보기 템플리트를 렌더링합니다. |
res.send() | 다양한 유형의 응답을 전송합니다. |
res.sendFile() | 파일을 옥텟 스트림의 형태로 전송합니다. |
res.sendStatus() | 응답 상태 코드를 설정한 후 해당 코드를 문자열로 표현한 내용을 응답 본문으로서 전송합니다. |
라우팅 모듈화
앞서 직접 구현했던 서버 부분에서 라우팅을 모듈화함으로써 코드를 분리하고, 관리할 수 있습니다. 이는 중복성과 오타가 감소할 수 있습니다.
const flights = require('../repository/flightList');
// 항공편 예약 데이터를 저장합니다.
let booking = [];
module.exports = {
// [GET] /book 요청을 수행합니다.
// 전체 데이터 혹은 요청 된 flight_uuid, phone 값과 동일한 예약 데이터를 조회합니다.
findById: (req, res) => {
이는 항공편 예약 기능을 구현하는 파일 상단 일부분입니다. module.exports를 이용해서 해당 방법들을 export 시킵니다.
=> 해당 코드에서처럼 module.exports 객체 내부에 하나의 변수에다가 (req, res) ~~ 로 간단하게 코드를 구현할 수 있습니다. 이 파일은 라우터를 관리하는 파일에서 받아서 아래와 같이 구현할 수 있습니다.
const { findById, create, deleteById } = require('../controller/bookController');
const express = require('express');
const router = express.Router();
router.get('/', findById);
router.post('/', create);
router.delete('/', deleteById);
module.exports = router;
라우터를 관리하는 파일에서 require로 export된 기능들을 받아오고, express.Router를 이용해서 정리를 할 수 있습니다.
express.Router 출처
express.Router 클래스를 사용하면 모듈식 마운팅 가능한 핸들러를 작성할 수 있습니다. Router 인스턴스는 완전한 미들웨어이자 라우팅 시스템이며, 따라서 “미니 앱(mini-app)”이라고 불리는 경우가 많습니다.
const flightRouter = require('./router/flightRouter');
const bookRouter = require('./router/bookRouter');
const airportRouter = require('./router/airportRouter');
app.use('/flight', flightRouter);
app.use('/book', bookRouter);
app.use('/airport', airportRouter);
app.js 폴더에서는 라우터를 관리하는 폴더를 require로 받아와서 app.use()를 통해서 엔드포인트에 따른 라우터를 설정할 수 있습니다.
이를 통해서 app.js 파일을 간단화 할 수 있으며, 각 엔드포인트별 기능 구현과 관리가 수월해질 수 있습니다.
자동차 공장에서는 컨베이어 벨트 위에 올려진 자동차의 뼈대에, 각 공정마다 부품을 추가합니다. 모든 부품이 추가되면 완성된 자동차가, 어딘가 문제가 있다면 불량품이 결과물로 나오게 됩니다. 미들웨어는 자동차 공장의 공정과 비슷합니다. 컨베이어 벨트 위에 올라가 있는 request에 필요한 기능을 더하거나, 문제가 발견된 불량품을 밖으로 걷어내는 역할을 합니다.
미들웨어는 express의 가장 큰 장점 입니다.
미들웨어가 할 수 있는 일
1. cors 헤더 자동 적용
2. body를 text든 json이든 알아서 잘 해결해줌
3. 에러처리와 디버깅에 용이(모든 요청에 대해 url이나 메소드를 확인해줌)
4. 권한에 따른 처리 가능(헤더에 있는 인증정보를 통해서)
5. prefix가 중복될 때 라우팅을 편하게
Express 앱에서 사용하기 위한 미들웨어 작성 출처
개요
미들웨어 함수는 요청 오브젝트(req), 응답 오브젝트 (res), 그리고 애플리케이션의 요청-응답 주기 중 그 다음의 미들웨어 함수 대한 액세스 권한을 갖는 함수입니다. 그 다음의 미들웨어 함수는 일반적으로 next라는 이름의 변수로 표시됩니다.
미들웨어는 말 그대로 프로세스 중간에 관여하여 특정 역할을 수행합니다. 수많은 미들웨어가 있지만, 가장 단순한 미들웨어 로거(logger)를 예로 들겠습니다. 로거는 디버깅이나, 서버 관리에 도움이 되기 위해 console.log 로 적절한 데이터나 정보를 출력합니다. 데이터가 여러 미들웨어를 거치는 동안 응답할 결과를 만들어야 한다면, 미들웨어 사이사이에 로거를 삽입하여 현재 데이터를 확인하거나, 디버깅에 사용할 수 있습니다.
미들웨어 함수는 다음과 같은 태스크를 수행할 수 있습니다.
- 모든 코드를 실행.
- 요청 및 응답 오브젝트에 대한 변경을 실행.
- 요청-응답 주기를 종료.
- 스택 내의 그 다음 미들웨어를 호출.
현재의 미들웨어 함수가 요청-응답 주기를 종료하지 않는 경우에는 next()를 호출하여 그 다음 미들웨어 함수에 제어를 전달해야 합니다. 그렇지 않으면 해당 요청은 정지된 채로 방치됩니다.
다음 예시에 미들웨어 함수 호출의 요소가 표시되어 있습니다.
위 그림은 endpoint가 /이면서, 클라이언트로부터 GET 요청을 받았을 때 적용되는 미들웨어입니다. 파라미터의 순서에 유의해야 합니다. req, res는 우리가 잘 아는 요청(request)/응답(response)이고, next는 다음 미들웨어를 실행합니다. 위 그림을 살펴보면, 미들웨어 내부에서는 아무런 작업을 하고 있지 않습니다. 그저 next() 함수를 호출하여 다음 미들웨어로 데이터를 전달하고 있습니다.
var express = require('express');
var app = express();
var myLogger = function (req, res, next) {
console.log('LOGGED');
next();
};
app.use(myLogger);
app.get('/', function (req, res) {
res.send('Hello World!');
});
app.listen(3000);
myLogger 이름의 미들웨어 함수를 만들고 미들웨어 함수를 로드하려면 미들웨어 함수를 지정하여 app.use()를 호출합니다.. 위의 코드는 루트 경로(/)로 라우팅하기 전에 myLogger 미들웨어 함수를 로드합니다.
미들웨어의 로드 순서는 중요하며, 먼저 로드되는 미들웨어 함수가 먼저 실행됩니다.
루트 경로에 대한 라우팅 이후에 myLogger가 로드되면, 루트 경로의 라우트 핸들러가 요청-응답 주기를 종료하므로 요청은 절대로 myLogger에 도달하지 못하며 앱은 “LOGGED”를 인쇄하지 않습니다.
미들웨어 함수 myLogger는 단순히 메시지를 인쇄한 후 next() 함수를 호출하여 스택 내의 그 다음 미들웨어 함수에 요청을 전달합니다.
애플리케이션 레벨 미들웨어
app.use() 및 app.METHOD() 함수를 이용해 애플리케이션 미들웨어를 앱 오브젝트의 인스턴스에 바인드하십시오. 이때 METHOD는 미들웨어 함수가 처리하는 요청(GET, PUT 또는 POST 등)의 소문자로 된 HTTP 메소드입니다.
다음 예에는 마운트 경로가 없는 미들웨어 함수가 표시되어 있습니다. 이 함수는 앱이 요청을 수신할 때마다 실행됩니다.
var app = express();
app.use(function (req, res, next) {
console.log('Time:', Date.now());
next();
});
다음 예에는 /user/:id 경로에 마운트되는 미들웨어 함수가 표시되어 있습니다. 이 함수는 /user/:id 경로에 대한 모든 유형의 HTTP 요청에 대해 실행됩니다.
app.use('/user/:id', function (req, res, next) {
console.log('Request Type:', req.method);
next();
});
아래에는 하나의 마운트 경로를 통해 일련의 미들웨어 함수를 하나의 마운트 위치에 로드하는 예가 표시되어 있습니다. 이 예는 /user/:id 경로에 대한 모든 유형의 HTTP 요청에 대한 요청 정보를 인쇄하는 미들웨어 하위 스택을 나타냅니다.
app.use('/user/:id', function(req, res, next) {
console.log('Request URL:', req.originalUrl);
next();
}, function (req, res, next) {
console.log('Request Type:', req.method);
next();
});
애플리켄이션 레벨 미들웨어의 사용 방법은 다양해서 필요할 때마다 찾아보고 구현하면 좋을 듯 합니다.
라우터 레벨 미들웨어
라우터 레벨 미들웨어는 express.Router() 인스턴스에 바인드된다는 점을 제외하면 애플리케이션 레벨 미들웨어와 동일한 방식으로 작동합니다.
var router = express.Router();
router.use() 및 router.METHOD() 함수를 사용하여 라우터 레벨 미들웨어를 로드하십시오.
다음 예의 코드는 위에서 애플리케이션 레벨 미들웨어에 대해 표시된 미들웨어 시스템을 라우터 레벨 미들웨어를 사용하여 복제합니다.
var app = express();
var router = express.Router();
// a middleware function with no mount path. This code is executed for every request to the router
router.use(function (req, res, next) {
console.log('Time:', Date.now());
next();
});
오류 처리 미들웨어
오류 처리 미들웨어에는 항상 4개의 인수가 필요합니다. 어떠한 함수를 오류 처리 미들웨어 함수로 식별하려면 4개의 인수를 제공해야 합니다. next 오브젝트를 사용할 필요는 없지만, 시그니처를 유지하기 위해 해당 오브젝트를 지정해야 합니다. 그렇지 않으면 next 오브젝트는 일반적인 미들웨어로 해석되어 오류 처리에 실패하게 됩니다.
다른 미들웨어 함수와 동일반 방법으로 다음과 같이 오류 처리 미들웨어 함수를 정의할 수 있지만, 오류 처리 함수는 3개가 아닌 4개의 인수, 구체적으로 말하면 (err, req, res, next) 시그니처를 갖는다는 점이 다릅니다.
app.use(function(err, req, res, next) {
console.error(err.stack);
res.status(500).send('Something broke!');
});
오류 처리 미들웨어는 다른 app.use() 및 라우트 호출을 정의한 후에 마지막으로 정의해야 하며, 예를 들면 다음과 같습니다.
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
app.use(bodyParser());
app.use(methodOverride());
app.use(function(err, req, res, next) {
// logic
});
요청 헤더에 사용자 인증 정보가 담겨있는지 확인할 때
(advanced challenges)
다음은 HTTP 요청에서 토큰이 있는지 여부를 판단하여, 이미 로그인한 사용자일 경우 성공, 아닐 경우 에러를 보내는 미들웨어 예제입니다.
토큰(Token): 주로 사용자 인증에 사용하며, Authentication을 학습할 때 다룹니다.
app.use((req, res, next) => {
// 토큰 있니? 없으면 받아줄 수 없어!
if(req.headers.token){
req.isLoggedIn = true;
next()
} else {
res.status(400).send('invalid user')
}
})
[코드] 토큰을 통해 로그인 여부를 확인하는 미들웨어 예시
로그인 없이 웹사이트에 접근을 시도했을 때, 로그인 창 등으로 되돌려 보내는 경우를 경험해 본 적이 있을 겁니다. 서버에서는 요청에 포함된 데이터를 통해 미들웨어가 요구하는 조건에 맞지 않으면, 불량품으로 판단하고 돌려보내도록 구현할 수 있습니다.
res.location(path)
Sets the response Location HTTP header to the specified path parameter.
response location header에 특정 경로 파라미터를 담을 수 있습니다.
res.location('/foo/bar')
res.location('http://example.com')
res.location('back')
=> 위에서 구현했던 book POST 부분에 location header를 지정해보았습니다.
node.js 디버깅
"scripts": {
"test": "jest --forceExit --runInBand",
"start": "node --inspect-brk statesairline/app.js",
"report": "jest --forceExit --runInBand --json --outputFile=report.jest.json",
"submit": "codestates-submission"
},
구현 중인 파일의 package.json 에서 scripts 의 start에 위와 같이 --inspect-brk 를 넣습니다. 그리고 npm start를 할 경우 디버깅을 할 수 있는 페이지가 로딩 됩니다. => req, res도 확인할 수 있으며, break point를 통해서 어디서 에러가 발생하는 지 확인할 수 있습니다.
'~2022 작성 글 > TIL' 카테고리의 다른 글
TIL 22 (2021.10.28) (0) | 2021.10.28 |
---|---|
TIL 21 (storybook, CSS방법론, styled-component, Ref)(2021.10.27) (0) | 2021.10.27 |
TIL 19 (고차컴포넌트, content-type,express.js) (2021.10.25) (0) | 2021.10.25 |
TIL 18 (2021.10.24) (0) | 2021.10.24 |
TIL 17 (2021.10.23) (0) | 2021.10.23 |