260106 - Re:zero부터 시작하는 Node.js

LIHA·2026년 1월 5일
post-thumbnail

yarn.lock이 생겨야 하는데 왜 자꾸 package-lock.json이 생기는거야?

npm install -g yarn 을 해준다 << 여기서 글로벌로 선언 안했을 가능성 高
yarn init -y 를 친다
yarn add express 를 친다

위 순서대로 했는데도 package-lock.json이 생긴다면 그냥 조용히 삭제해주자.
아마 npm install yarn 때 생기는 경우가 많을 것 (-g 해줘야 안 생긴다)
지금은 기억하겠지만 기억하지 못할 나중을 위해 적자면, lock 파일이 두개 있어선 안된다. yarn.lock을 쓰든 package-lock.json을 쓰든 한개만 남겨야 한다. 이 둘은 git에 커밋되어야 한다.

TCP - 악수만 세 번 / UDP - 입벌려 패킷 들어간다

TCP의 특징 - 생일파티 초대장 돌리기

  • 신뢰성
  • 연결 기반
  • 데이터 순서 보장

UDP의 특징 - 공원의 물총싸움

  • 비연결성
  • 빠른 전송
  • 패킷 순서 미보장, 손실 가능성

HTTP는 전송 계층의 TCP 연결 위에서 돌아가는 프로토콜

현대 웹의 근간. TCP랑은 다르게 7층인 애플리케이션 계층에서 사용된다. 웹 소켓 또한 HTML5에서 등장한 TCP 기반 통신이라 7층에서 돌아간다.
하지만, 그냥 TCP 통신은? 4층인 전송 계층의 프로토콜. 그러니 헤더가 무겁든 어쩌든 TCP를 이용한 방법이 당연히 더 빠르다.

HTTP의 특징

  • 효율성 -> 필요한 시점에만 연결한다
  • 상태 비저장성 -> Stateless (철수가 늘 먹던걸로. 해도 사장님은 모르는게 HTTP)

require("모듈") 형태의 CJS는 생각보다 아직 현업에 많다고 한다

유데미 강의가 require 문을 쓰는 형태라 당황했다. 그러고보니 구매해놓은 다른 Node 강의도 ES5 이하의 CJS 문법을 쓴다.

서버를 띄우려고 했더니 permission denied - 네트워크 드라이버의 문제

Error: listen EACCES: permission denied 0.0.0.0:3000

아니 이게 뭐야. 무슨 permission이 왜 denied야?
하지만 참고 블로그 덕분에 무사히 해결했다. 네트워크 드라이브를 멈췄다가 다시 실행해주면 ok

  1. cmd를 관리자 권한으로 실행한다
  2. net stop winnat 을 입력한다
  3. net start winnat 을 입력한다

이 과정으로 해결.

엉뚱하지만 문득 서버 주소가 궁금했다

역시나 고마운 스택 오버플로우 웨건이 해결해 주었다.

// Source - https://stackoverflow.com/a/41540536
// Posted by BlackMamba
// Retrieved 2026-01-12, License - CC BY-SA 3.0

var http = require('http');
var server = http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(8080);
console.log('Server listening:', `http://${server.address().address}:${server.address().port}`);

이런식으로 쓰라고 하기에 똑같이 써보니 잘 되었다.

커맨드라인에서 HTTP요청을 보내는 명령어 curl

이 명령어는 git bash에서 사용해야 하니 터미널 추가 시 git bash를 선택해주자. -v는 요청과 응답 송수신의 상세를 볼 수 있는 명령어이다.

curl http://localhost:3000 -v

이렇게 무사히 송수신 되었음을 볼 수 있다. 저기서 Accept:*/* 아랫줄이 비어있는 이유는 요청 시에 아무 내용도 넣지 않았기 때문이라고.
아울러 잊고있던 localhost 주소가 127.0.0.1임을 상기했다 (...)

그래서 라우터는 정확히 무엇일까

server.listen(PORT, () => {
  console.log(`Server is listening on port ${PORT}`);
});

이렇게 써있는 것을 보고 서버는 3000번 포트에서 HTTP 트래픽 수신을 대기한다 고 한다. 서버 자체는 HTTP 트래픽이 언제 어디서 발생하는지 신경쓰지 않으며, 요청이 오면 정의한 콜백함수를 실행할 뿐이다.

그래서 요청의 경로에 따라 다른 응답을 보내주려면 개발자가 직접 구현해야 한다. 이것이 라우팅이고, 이렇게 정의된 개별 로직의 단위가 라우터.

MIME-TYPE? 문서나 데이터의 형식을 나타내는 정보

웹 개발에서 이는 상당히 중요하다. 여러 종류의 타입이 있는데 일부를 보자면 다음과 같다.

text/html
text/plain
text/css
application/javascript
image/jpeg
image/png
application/pdf
application/json

웹서버에서는 이런 컨텐츠 타입을 분석하여 MIME 타입을 설정하고, HTTP 응답헤더의 컨텐츠 타입 필드에 포함하여 클라이언트에게 전송한다.

정적 데이터가 수백만인데 일일이 if문을 걸 수는 없다 - 정적 파일 처리 함수를 구현해보자

const serveStatic = (rootDir, req, res) => {
  const filePath = path.join(rootDir, req.url);
  fs.readFile(filePath, (err, data) => {
    if (err) {
      if (err.code === "ENOENT") {
        res.writeHead(404, { "content-type": "text/html" });
        res.end("<h1> 404 Not Found! </h1>");
      } else {
        res.writeHead(500, { "content-type": "text/html" });
        res.end("<h1> 500 Internal Server Error! </h1>");
      }
    } else {
      const extname = path.extname(filePath);
      const content = contentType.getContentType(extname);
      res.writeHead(200, { "content-type": content });
      res.end(data);
    }
  });
};

우선 이런 식으로 최소한의 뼈대만 구현.

왜 자꾸 터지는걸까? res.end()가 또 있었기 때문

자꾸 이렇게 터지면서 홈페이지가 나오지 않는 것이었다. 메시지는 대강 클라이언트에 이미 응답을 보내고 나서 다시 헤더를 쓸 수 없다는 것 같았다.

문제의 부분은 여기였다. 이 가장 바깥 res.end()를 지워주니 정상적으로 출력되었다.

Powershell에선 touch로 새 파일을 만들 수 없다 - ni (new item)을 쓰자

부트캠프 때 touch로 새 파일을 만드시던 강사님의 모습이 떠올라 우클릭 하지 않고 CLI로 새 파일을 만들어보고 싶었는데, 파워쉘은 물론이고 깃배쉬에서도 touch가 먹히지 않는 것이다.

알고보니 touch는 Linux 명령어라고. Powershell에서는 ni .gitignore 하니 만들어졌다.

profile
갑자기 왜 춤춰?

0개의 댓글