kokoball의 devlog
article thumbnail
728x90

 

 

 

개발자들은 일을 시작할 때 npm run start 등 비슷한 명령어로 Dev Server를 띄우면서 시작을 하게 됩니다.

 

이 과정 속에서 일어나는 일은 모듈 번들러의 역할 등을 알고 있으면 어렴풋이 알게 되지만,

이번글은 조금 더 깊게 그 과정에서 일어나는 일을 자세히 알아 보려고 합니다.

 

(이 글은 React CRA와 webpack을 기준으로 작성되었습니다.)

 

우선 npm 이란?

npm은 Node Package Manager로 node로 실행할 수 있는 패키지들을 관리하는 도구이며, 개발자는 npm을 통해 다른 사람이 작성한 패키지를 다운로드하고, 업데이트하고, 삭제할 수 있습니다.

 

쉽게 생각해 보면 npm은 application을 설치 삭제 및 관리해 주는 앱스토어와 같은 역할을 하며,

npm을 이용해서 우리는 npm run start 같은 명령어를 정의하고 package.json를 통해 관리하게 됩니다.

 

그럼 package.json이란 무엇인가요?

package.jsonNode.js 프로젝트의 메타데이터 파일로, 프로젝트의 종속성, 스크립트, 구성 및 기타 세부 정보를 설명합니다.

일반적으로 이름, 버전, 작성자, 라이선스와 같은 프로젝트에 대한 정보가 포함되어 있습니다.

 

또한, 다른 Node.js 패키지에 대한 프로젝트의 종속성을 버전 번호와 함께 나열하여 프로젝트가 설정되거나 업데이트될 때 이러한 종속성을 자동으로 설치할 수 있습니다.

 

package.json 파일은 일반적으로 Node.js 프로젝트의 루트 디렉토리에 있으며 (npm init 명령을 실행 등) 프로젝트를 초기화할 자동으로 생성되며, 파일을 수동으로 만들고 수정하여 프로젝트의 종속성과 구성을 관리할 수도 있습니다.

💡 Node.js의 package.json 파일의 주요 목적 정리


종속성 관리: package.json 파일은 프로젝트에 필요한 종속성과 dev 종속성, 그리고 해당 버전 범위를 지정
메타데이터: 프로젝트의 이름, 버전, 설명, 작성자, 라이선스 및 기타 관련 정보 등 프로젝트에 대한 메타데이터를 포함
스크립트: npm run 명령을 사용하여 실행할 수 있는 스크립트(예: 빌드, 테스트, 시작 등)를 정의
구성: 주요 진입점, 저장소, 프로젝트를 실행하는 데 필요한 엔진 등 프로젝트의 다양한 측면을 구성
게시: 이름, 버전, 작성자, 라이선스 및 기타 관련 정보와 같이 패키지를 게시하는 방법에 대한 정보를 제공
호환성: 프로젝트와 호환되는 Node.js 버전 범위를 지정 가능

우리가 알아볼 npm run start 명령어도 package.json의 Script 섹션에 정의되어 있습니다.

그럼 npm run start 명령어를 실행하면?

npm run start 명령어를 실행하게 되면 환경 설정 및 Webpack 설정을 로드하여 애플리케이션이 실행되는 환경을 설정하고,

이후 웹팩은 Dev Server를 실행하게 됩니다. (실제 파일 속 코드 확인은 [링크]에서 확인)

 

이는 프로세스를 관리하고 파일 변경을 감시하며 변경 사항이 있을 때마다 다시 번들링 하여 브라우저에 반영하는 역할을 하게 됩니다.

 

Webpack Dev Server에 대해 실행 순서 및 설명을 자세히 보고 가겠습니다.

 

1. Webpack Dev Server 시작

  • webpack-dev-server 명령어를 실행하거나, 스크립트를 통해 서버를 시작합니다.
  • 이 서버는 코드 변경 사항을 실시간으로 반영하여 브라우저에 자동으로 업데이트하는 기능을 제공하며, 기본적으로는 localhost:3000에서 서버가 실행됩니다.

2. Webpack 설정 로드

  • 서버가 시작되면, 설정 파일(webpack.config.js)에서 정의된 devServer 옵션을 기반으로 서버 설정을 초기화합니다.
  • 이 설정 파일에는 엔트리 포인트, 로더, 플러그인, 출력 경로 등의 번들링 설정이 포함되어 있습니다.

3. 번들링 시작

  • Webpack은 엔트리 파일인 src/index.js를 시작으로, 모든 의존성을 따라가며 파일을 번들링 합니다.
  • 설정된 로더를 사용하여 각 파일을 처리하고, 최종적으로 JavaScript, CSS, 이미지 등의 파일을 하나의 번들 파일로 묶습니다.
  • Webpack Dev Server는 번들링 된 파일을 메모리에 저장하고, 개발 서버를 통해 이를 제공합니다.

4. 파일 감시 및 핫 모듈 교체(HMR)

  • Webpack Dev Server는 프로젝트 디렉터리의 파일 변화를 감시하며, 파일이 변경되면 Webpack은 해당 파일을 다시 번들링 하고, 변경된 내용을 브라우저에 실시간으로 반영하게 됩니다.
  • 이 기능을 통해 전체 페이지를 새로고침하지 않고도 변경된 모듈만 교체할 수 있습니다.

5. 브라우저와의 통신

  • 브라우저는 Webpack Dev Server에서 제공하는 번들 파일을 로드하여 애플리케이션을 실행하게 됩니다.
  • 이때 HTTP(S) 통신을 사용하여 주로 번들된 파일과 정적 자산을 브라우저에 제공하며, 파일이 변경되면, 서버는 WebSocket 통신 등을 통해 브라우저와 양방향 통신하여 실시간으로 변경 사항을 전달하고, 브라우저는 이를 반영하게 됩니다.

 

이 과정 중에서 주의 깊게 봐야 하는 부분은 번들링 부분입니다.

 

만약 이 부분이 없다면 프로젝트의 HTML, JS, 이미지 등 다양한 파일이 전부 HTTP 통신을 통해 요청되어 리소스를 가져오게 됩니다.

파일들의 크기가 작을 땐 상관이 없지만 규모가 커지게 되면, 파일의 요청이 많아져 통신량이 많아지게 되고 이는 성능 저하의 큰 원인이 됩니다.

 

또한, 트리 쉐이킹이나 코드 스플리팅(splitChunks) 통해 초기 로드 시간을 줄이는 등 성능 최적화를 이끌 수 있기 때문에 중요한 작업 중에 하나입니다.

 

브라우저가  번들링 된 파일을 받은 후 일어나는 일

브라우저가 번들링 된 파일을 받게 되면 우선 그중에서 index.html 파일을 로드하게 됩니다.

 

html 파일에는 번들된 JS 파일을 로드하는 script 태그가 포함되어 있으며, 이를 통해 번들된 JS 파일을 요청하고 로드하게 됩니다.

 

번들된 코드의 시작점은 일반적으로 'index.j(t)s' 파일입니다.

파일에서 React 초기화가 이루어지며 React 애플리케이션의 루트 컴포넌트가 DOM 특정 요소에 마운트 됩니다.

// 루트 컴포넌트 예시
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));

 

이후 ReactDOM.render 함수가 루트 컴포넌트 id = "root" 인 DOM 요소에 렌더 단계와 커밋 단계를 거치며 렌더링 하게 됩니다.

(브라우저의 렌더링 과정은 이번 글에서 생략하도록 하겠습니다)

 

빠른 속도로 사랑받고 있는 Vite는 Webpack 대신 Rollup과 esbuild(or swc) 이용하여 비슷한 역할을 처리하며,

next.js SWC 사용하지만, 정확히는 swc-loader이나 next-swc-loaderwebpack 통해 webpack 번들이 제공된다고 합니다.

 

마치며

글을 시작하기 전에는 분명히 쓸 내용이 많았는데, 작성한 내용을 보니 역시나 좋은 글을 작성한다는 건 언제나 어려운 일인 거 같습니다.

그렇지만 앞으로도 어렴풋이 알고만 있던 부분들을 재정리하고 글을 작성하며, 시니어 개발자로 가는 여정을 이어가려고 합니다.

 

 

 

 

 

 

 

 

https://webpack.kr/plugins/split-chunks-plugin/

https://www.linkedin.com/pulse/reactjs-understanding-packagejson-package-lockjson-tejas-musale

https://crmerry.tistory.com/160

https://webpack.kr/guides/tree-shaking/

728x90
profile

kokoball의 devlog

@kokoball-dev

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!