시작하는 중
Next.js에서 yarn start를 하면 일어나는 일 본문
이전에 yarn dev를 입력하면 어떤 일이 일어나는가를 확인했던 경험이 있다.
https://mystacks.tistory.com/109
yarn dev를 하면 vite에서 일어나는 일
이 글은 2023년 5월 1일자 커밋인 1ee0014caa7ecf91ac147dca3801820020a4b8a0헤드를 기준으로 작성하였습니다. yarn dev를 하면 vite에서 일어나는 일 자신의 프로젝트에서 yarn dev를 하면 package.json에서 scripts의 "de
mystacks.tistory.com
이번엔 Next.js의 yarn start이다.
해당 포스팅은 2023년 7월 4일의 커밋인 f60b5621ac5c2e24e91bde80fd7d836b89a3b1b0 기준으로 작성
Next.js 프로젝트에서 package.json의 scripts를 통해서, yarn start가 어떤 커맨드인지를 알 수 있다.

yarn start는 next start와 같으니까 next 모듈로 간다.
next 모듈의 package.json을 보면 bin이 존재한다. bin은 해당 모듈의 진입점에 해당하는 것이다.

bin이 지정해준 경로로 이동해서 next.js 파일을 살펴본다.

해당 파일에서는 커맨드에 대한 처리가 이뤄지고 있는 듯 했다. 이유는 _commands라는 변수를 선언하고 있기 때문이다.

해당 파일로 이동하면, 재밌는 것들이 있다

여기서 그토록 찾던 start가 존재했다.. commands라는 Object의 key로 start가 있다.
그럼 next/dist/bin/next에서 이를 바탕으로 무언가를 하지 않을까?
commands는 다음과 같이 사용되고 있다.

동적 require가 끝나기를 기다리고, then 체이닝을 통해 가져온 메서드를 exec라는 인자로 받아서 실행하는 모습이다.
그럼 commands에서 가져오고 있는 "../cli/next-start"로 가볼 차례이다.

우선, 맞게 왔는지 검증해보기 위해 다음의 명령어를 실행해볼 것이다.
yarn start --help
이렇게 하면 다음의 결과가 출력되어야 한다.

잘 실행된다. 잘 온거 같다.

우리는 해당 파일에서 nextStart라는 함수를 선언하는 것을 볼 수 있다.

스크롤을 내리다보면, 여러 에러처리와 예외처리와 커맨드 처리를 거쳐서 await 문에 도착할 수 있다.
여기서 _startserver.startServer 메서드를 인자로 어떤 Object를 넣어서 실행한다.

전처리를 해서 가져온 인자들을 넘긴다. _startserver는

여기서 불러와서 저장해둔 것이다. 해당 경로로 가봐야한다.

이 파일의 중심인 startServer 메서드를 볼 것이다. 그 안의 코드블록들 중에서 sockets이라는 Set 인스턴스를 만드는 코드가 있다.

이건 밑에서 보겠지만, http 모듈의 res를 관리하는 Set이다. Set 중복이 없기 때문에, Set을 선택하지 않았나 싶다.
알고리즘에서 자주 사용하던 Set을 이런 곳에 쓰는게 좀 신기했다.
server를 선언하는 코드가 있다.

http 모듈을 사용하고 있다. node를 통한 서버를 여는 방법을 아직 몰라서 어떻게 할까 하다가 좋은 글을 발견했다.
http 모듈에 대한 설명과 예시를 보여주셔서 코드가 어떤 것들을 의미하는지 이해하기 쉬웠다.
https://kss7547.tistory.com/43
다시 돌아와서,
next.js는 server.createServer를 통해 웹 서버를 열고, server라는 이름에 저장했다. 여기에 들어가는 콜백함수는 클라이언트가 서버에 요청을 보낼 때마다 콜백함수들이 실행된다고 한다.
sockets에 res를 저장하고, res.on "close" 의 콜백함수로 sockets의 res를 제거하는 함수를 넘긴다.
이 close는 클라이언트가 연결을 끊어버리거나, response가 잘 전달되어 연결이 종료된 경우를 의미한다. res.end, res.destroy 메서드로 종료할 수 있다.

server.on을 통해 "upgrade"와 "error"이벤트에 대한 핸들링을 추가하고 있다.

server.listen이 실행될 때 발생하는 이벤트인 listening에 대한 server.on도 추가하고,
마침내 서버를 시작한다!
그리고 긴~ try catch 구문이 시작되는데, 이는 라우팅과 프록시 서버에 대한 설정 코드인 것 같다.


여튼, 이 startServer 메서드가 실행된 후의 서버에 대한 처리는 다음과 같이 정리할 수 있다.
1. http 모듈의 응답 객체를 담을 sockets를 선언한다.
2. http 모듈의 createServer를 실행시켜 서버를 연다.
3. server.on을 통해 서버에 발생되는 upgrade, error, listening 이벤트에 대한 리스너를 추가한다.
4. try 구문에서 라우팅과 프록시 서버를 설정한다.
그리고 teardown을 선언하고 리턴해준다.

server를 닫고, sockets에 담긴 res들을 삭제하고, 파괴시킨다. worker도 종료시킨다.
이 반환되는 teardown은 어디로 갈까?
솔직히 잘 모르겠다.. 왜냐하면 이를 실행한 구문은
next/dist/server/lib/start-server.js의 startServer를 실행한,
next/dist/cli/next-start.js에 있는데 이를 반환하여 저장하거나 실행하지 않기 때문이다..

그래서 종료는 모르겠다.
요약
1. Next.js 프로젝트에서 yarn start를 하면 next 모듈의 package.json에 의해서 next/dist/bin/next.js가 실행된다.
2. 여기서 ../lib/commands.js의 Object인 commands를 가져오고, key가 start로 매핑된 동적 require를 기다린다.
3. 가져오기가 끝나면, then 체이닝에 의해 가져온 함수인 nextStart를 실행한다.
4. nextStart는 ../server/lib/start-server.js의 startServer 메서드를 실행시킨다.
5. startServer는 http 모듈을 사용하며, server를 만들고, 이벤트들을 추가하고, 서버를 연다.
6. 그 다음, 라우터와 프록시 설정을 해준다.
7. 그리고 teardown 함수를 선언하고 리턴하는데, 이 함수는 열어둔 서버를 닫고 보낸 응답들을 파괴하고 worker를 종료시키는 함수를 리턴한다.
8. 그리고 반환된 이 teardown은 어디서 실행하는가는 모르겠다.
reference
https://github.com/vercel/next.js
https://leejabba.gitbooks.io/node-js/content/http-baa8-b4c8.html#1
'자바스크립트' 카테고리의 다른 글
SPA router 만들어보기 (0) | 2023.07.07 |
---|---|
JavaScript History API (0) | 2023.06.06 |
웹팩 webpack 설정 알아보기 (0) | 2023.05.24 |
함수형 프로그래밍 (0) | 2023.05.15 |
모듈, 번들러, 모듈 번들러의 개념과 등장한 이유 (0) | 2023.05.06 |