이전 게시글 (https://0422.tistory.com/312) 을 통해 나름대로 웹서버를 구현해보았다.
그렇다면 진짜 사용되는 모듈들은 어떻게 구현되어있는지 확인해보자.
webpack-dev-server
이녀석은 서버를 어떻게 띄우고 있을까?
이건 examples에 있는 코드인데, 확인해보면 lib/Server에서 Server Class를 가져와서 server인스턴스를 만든 후 server.start()를 통해 시작시키고 있는 것을 확인할 수 었다.
그럼 Server Class를 뜯어보자.
https://github.com/webpack/webpack-dev-server/blob/master/lib/Server.js
여기서 확인해보자.
확인해볼만한 부분은 1번과 2번일 것이다.
일단 initialize를 한 후에 어떤 일을 할 것이고, 이후에 this.server.listen해서 서버를 열어주고 있다.
그럼 더 중요한 부분은 initialize함수일 것이다. 해당 함수를 살펴보자.
initialize함수
여기서도 두가지가 중요해보인다. setupApp과 createServer가 그것이다.
setupApp
getExpress? 어디서 본 이름이다.
놀랍게도, webpack-dev-server는 express였다! memorize는 뭔가 캐싱을 해주는 것으로 보인다.
그러면 다음으로 createServer메서드를 살펴보자
이 함수는 this.server를 할당해주는데, 동적으로 require해와서 createServer를 해주는 것으로 보인다.
그럼 type에는 어떤게 올 수 있을까? 이건 JSDocs로 적힌 ServerConfiguration을 살펴보면 될 것이다.
아하, node의 모듈들이 적혀있다.
spdy는 구글에서 개발한 웹 콘텐츠 전송을 위한 개방형 네트워크 프로토콜이다.
npm모듈이 따로 있다.
이렇게 만들어진 서버의 두번째 인자로 express를 넘기는 것이다. 이렇게 하면 express의 미들웨어를 그대로 사용할 수 있어서 그런 것으로 보인다.
그럼 Static File들은 어떻게 관리되는거지?
궁금해서 static단어를 찾아봤더니 getStaticItem이라는 함수가 보인다.
optionsForStatic이라는 객체를 받아서 정적 파일들을 얻어오는 함수로 보인다.
이 객체는 directory, publicPath, serveIndex, staticOptions, watch로 구성된 것 같다.
일단 그럼 이 함수를 어디서 쓰는지 보자.
options.static에 할당된다.
이 객체 프로퍼티의 쓰임새를 찾다보면 어떻게 웹서버가 구성되는지 확인할 수 있을것이다!
setupMiddlewares에서 이걸 찾을 수 있었다.
express-static을 통해 static설정을 해준다는 것을 알아냈다.
이제 Experss로 넘어가야 할 것 같다....
정확히는 express의 static메서드를 보면 된다!
https://github.com/expressjs/express
express.static을 찾아서
이친구도 serve-static이라는 친구에게 의존성을 갖고 있었다.
뭔가 공무원 전화돌리는 느낌이지만... 인내심을 갖고 좀더 돌아보자.
https://github.com/expressjs/serve-static
다행히도 이친구는 구현 코드가 굉장히 짧다(아까 녀석들에 비하면)
하나씩 살펴보자.
root를 받아서 파일을 서빙해주는 함수다. 다른건 다 필요없고, 좀더 밑을 보자.
GET인경우, send로 스트림을 만들어주고, 이걸 통해서 파일을 보내주는 것으로 보인다....
도대체 Content-type은 어디서 정해진다는 말인가..
자 그럼 send모듈로 넘어가보자...
https://github.com/pillarjs/send.git
Content-Type으로 찾아왔다.
mime.lookup이라는 함수에 path를 넘겨서 type을 받아오고, 이걸로 res.setHeader를 해줘서 Content-Type을 설정해주었다!
이제 Content-type이 어떻게 설정되는지는 알아냈다.
기왕 이렇게 된거 mime 라이브러리도 보자
https://github.com/broofa/mime
standardTypes와 othersType을 받아서 Mime인스턴스를 만들고 이걸 export해준다.
생성자를 보니 그냥 이걸 Map으로 전환해주는 듯 하다.
define에서 하는일을 좀 더 알아보고 싶어서 gpt에게 물어봤다.
MIME의 충돌 유형까지 검사하는 것으로 보인다.
자 이제 원본 type들을 보자.
드디어 원본 매핑 파일을 찾아냈다....!
이런식으로 Content-Type을 설정하고, 서버를 띄워준다는 것을 알 수 있었다.
Content-Type을 설정하기 위해 이런 의존성을 갖는다는걸 알 수 있었다.
과연 라이브러리 하나에 얼마나 많은 모듈이 구성되어있을지 궁금하기도 했고, mime라이브러리 만든사람 레포에 npmgraph라는게 있어서 사용해봤다.
총 58개의 라이브러리로 구성되어있었다.
그럼 webpack-dev-server는 어떨까?
잘 보이지도 않는다...
204개의 라이브러리로 구성되어있다.
결론
생각보다 라이브러리간 의존성이 많았고, 간단한 기능이라도 다양한 경우가 있기때문에 다른 라이브러리를 쓰는 경우가 많다. 직접 구현한 것과 근본적으로 다르지는 않았지만, 좀 많이 다른 부분이 있었다.
추측하기보다는 직접 코드를 뜯어보는 것이 좋다는 것을 알게되었고, 그 연습을 할 수 있어서 좋았다.
다른 라이브러리 코드를 뜯어보는데에도 부담감이 더 줄어들 것 같다.