* 프로그래머스, 타입스크립트로 함께하는 웹 풀 사이클 개발(React, Node.js) 5기 강의 수강 내용을 정리하는 포스팅.
* 원활한 내용 이해를 위해 수업에서 제시된 자료 이외에, 개인적으로 조사한 자료 등을 덧붙이고 있음.
JavaScript 런타임 환경. 브라우저 외부에서도 JavaScript를 실행할 수 있게 만들어주는 플랫폼.
웹 브라우저, 프론트엔드 개발에만 사용되던 Javascript를 브라우저 바깥에서 사용하도록 만든 만큼, 주로 서버 사이드 개발에 사용된다.
크롬 브라우저에서 JavaScript를 처리하는 구글의 V8 JavaScript 엔진을 사용하여 JavaScript 코드를 빠르게 실행. 이를 활용해 JavaScript를 브라우저가 아닌 서버에서도 실행할 수 있도록 구현되어있다.
비동기(non-blocking) / 단일 스레드로 작동. 특정 작업을 수행하는 동안 다른 작업이 동시에 처리될 수 있고, 이벤트 루프 등을 통해 많은 요청의 효율적인 처리를 수행한다.
Node.js의 패키지 관리 시스템. JavaScript 라이브러리와 패키지를 설치하고 관리할 수 있게 해준다.
수많은 오픈소스 라이브러리와 패키지가 있어, 다양한 기능을 손쉽게 구현할 수 있다.
npm도 많은 개선을 거쳐 초기 문제들이 상당히 해결된 상태.
5 버전 이후 성능과 의존성 관리에서 개선이 이루어졌고, 특히 최근의 npm 7과 8, 9 버전에서는 Yarn에 비해 큰 차이가 없을 정도로 발전했다.
다만, 특정 기능(예: PnP, 오프라인 캐시, 모노레포 관리 등)에 대해 Yarn이 여전히 선호되는 경우가 있다. 따라서 npm과 yarn의 특징을 잘 살펴보고 어느 것을 선택할지 고민해봐야 한다.
추가로 커뮤니티와 생태계 규모 측면에서는 npm쪽이 더 거대하다.
let http = require('http');
function onRequest(request, response) {
response.writeHead(200, {'Content-Type' : 'text/html'});
response.write('Hello Node.js');
response.end();
}
http.createServer(onRequest).listen(8888);
let http = require('http');
function onRequest(request, response) {
response.writeHead(200, {'Content-Type' : 'text/html'});
응답 헤더를 설정합니다. 여기서 200은 상태 코드(성공)를 나타내며, Content-Type 헤더는 응답의 내용이 HTML 형식임을 지정한다.
응답 코드? 상세 내용은 이전 포스팅 참조.
response.write('Hello Node.js');
response.end();
http.createServer(onRequest).listen(8888);
index.js
const { startServer } = require('./server');
const router = require('./routes/routes');
const { handle } = require('./requestHandler/requestHandler');
startServer(3000, router.route, handle);
server.js
const http = require('http');
const url = require('url');
function startServer(port = 3000, route, handle) {
const server = http.createServer((req, res) => {
// 요청 URL을 파싱하여 경로 추출
let pathname = url.parse(req.url).pathname;
// /favicon.ico 요청 무시
if (pathname === '/favicon.ico') {
res.writeHead(204); // No Content 응답 코드
res.end();
return;
}
route(pathname, handle, req, res); // 경로와 핸들러, 요청 및 응답 객체 전달
});
server.listen(port, () => {
console.log(`웹 서버가 해당 주소에서 동작 중입니다. :: http://localhost:${port}`);
});
}
module.exports = { startServer };
routes.js
function route(pathname, handle, req, res) {
// 한글 URL도 정상 출력 하도록 디코딩
const decodedPathname = decodeURIComponent(pathname);
if (typeof handle[decodedPathname] == 'function') {
handle[decodedPathname](req, res, decodedPathname);
} else {
res.writeHead(404, { 'Content-Type': 'text/plain; charset=UTF-8' });
res.write('404 Not Found, 찾으시는 페이지는 존재하지 않는 페이지입니다.');
res.end();
console.log(`No handler found for ${decodedPathname}`);
}
}
module.exports = { route };
requestHandler.js
function main(req, res) {
console.log('main');
res.writeHead(200, { 'Content-Type': 'text/plain; charset=UTF-8' });
res.write('Main 페이지');
res.end();
}
function name(req, res, decodedPathname) {
console.log('Requested pathname: ' + decodedPathname); // 요청된 경로를 콘솔에 출력
res.writeHead(200, { 'Content-Type': 'text/plain; charset=UTF-8' });
res.write(decodedPathname);
res.end();
}
// 라우팅을 위한 매핑 객체
// URL 경로를 키(key)로, 각 경로에서 수행할 **핸들러 함수(값, value)**를 연결
let handle = {};
handle['/'] = main;
handle['/이유승'] = name;
module.exports = { handle };
역할:
- 서버를 시작하고 필요한 모듈을 불러옵니다. server.js의 startServer 함수에 포트 번호, route 함수, handle 객체를 인수로 전달하여 서버를 초기화합니다.
작업 흐름:
- index.js는 서버를 실행할 때 가장 먼저 호출되며, server.js의 startServer 함수로 제어를 넘깁니다.
역할:
- HTTP 서버를 생성하고 클라이언트 요청을 처리합니다. route 함수와 handle 객체를 사용하여 요청 URL을 기반으로 적절한 라우팅을 수행합니다.
작업 흐름:
- 클라이언트 요청이 들어오면 URL 경로를 추출하고, 해당 경로를 route 함수에 전달하여 콘솔에 경로를 출력하게 합니다. 이후 handle 객체를 사용하여 경로에 맞는 핸들러 함수를 호출해 요청을 처리합니다.
역할:
- 서버가 요청된 URL 경로를 콘솔에 출력합니다. URL이 한글일 경우 인코딩된 URL을 디코딩하여 콘솔에 출력할 수 있도록 처리합니다.
작업 흐름:
- server.js에서 전달된 URL 경로를 decodedPathname으로 디코딩하고, handle 객체에 해당 경로가 있는지 확인합니다. 일치하는 핸들러가 없을 경우 콘솔에 "No handler found" 메시지를 출력합니다.
역할:
- 각 URL 경로에 맞는 핸들러 함수들을 정의하고, handle 객체에 경로별로 매핑합니다. 요청된 경로에 맞는 함수를 통해 클라이언트에 응답을 보냅니다.
작업 흐름:
- handle 객체는 server.js에서 사용되어, 요청된 URL에 따라 매핑된 핸들러 함수가 실행됩니다. 각 핸들러 함수는 요청 URL을 출력하고, 필요한 경우 특정 HTML 페이지를 응답으로 전송하거나 데이터베이스 작업을 수행합니다.
테니스 라켓 쇼핑몰 만들어보기.
- 메인 페이지와 주문 목록 페이지로 이루어진 초간단 실습 프로젝트.
효율적인 프로젝트 관리를 위해, 관련 파일은 Git - Github로 관리하도록 진행하였음.
메인 페이지 및 주문 목록 페이지 UI.
이외에도 금일 구현한 Node.js 기반 백엔드 파트도 동일한 Github 저장소에서 관리함.