`npm run dev`의 마법, 그 숨겨진 비밀을 파헤치다!
`npm run dev` 명령어 실행 시, 쉘(Shell)은 npm CLI를 실행하고, npm은 `package.json`의 스크립트를 읽음
npm은 자식 프로세스(Child Process)를 생성하여 `vite` 명령어를 실행하며, `vite`는 `esbuild`를 사용하여 의존성(Dependencies)을 사전 번들링(Pre-bundling)함
Vite는 HTTP 서버를 시작하여, 브라우저 요청에 따라 파일을 읽고 변환하며, Hot Module Replacement(HMR)를 지원함
npm과 쉘(Shell) 환경
본문에서는 `npm run dev` 실행 시 쉘(Shell)이 npm을 찾아 실행하는 과정을 설명한다. 쉘은 PATH 환경 변수(PATH Environment Variable)를 참조하여 npm의 위치를 확인하고, npm CLI를 실행한다.
npm CLI: Node.js 스크립트로, `package.json` 파일을 읽어 실행할 명령어를 결정
자식 프로세스(Child Process) 생성: npm은 자식 프로세스를 생성하여 `dev` 명령어를 실행
`./node_modules/.bin` 추가: npm은 자식 프로세스의 PATH에 `./node_modules/.bin`을 추가하여, 로컬에 설치된 실행 파일(예: vite)을 찾도록 함
이러한 과정은 개발 환경에서 명령어 실행의 기본 원리(Basic Principle of Command Execution)를 보여준다.
Vite의 esbuild를 활용한 번들링(Bundling)
Vite는 esbuild를 사용하여 개발 서버의 성능을 향상시킨다. esbuild는 Go로 작성되어 매우 빠른 속도로 번들링을 수행한다.
CommonJS를 ESM으로 변환: 브라우저에서 ESM(ES Modules)을 지원하므로, esbuild는 CommonJS를 ESM으로 변환
모듈 병합: lodash와 같이 내부 파일이 많은 패키지를 하나의 파일로 병합하여 HTTP 요청(HTTP Request) 수를 줄임
캐싱(Caching): `.vite/deps/` 디렉토리에 캐싱하여, node_modules 변경 시에만 다시 번들링 수행
이러한 최적화는 개발 서버의 빠른 시작 시간(Fast Startup Time)과 HMR(Hot Module Replacement) 성능 향상에 기여한다.
Vite 개발 서버의 동작 원리
Vite는 단순한 Node.js HTTP 서버를 사용하여 개발 서버를 구현한다. 브라우저의 요청에 따라 파일을 읽고 변환하여 제공한다.
파일 변환: JSX, TypeScript, CSS 등을 변환하여 브라우저에서 실행 가능한 형태로 제공
HMR(Hot Module Replacement): 코드 변경 시, 전체 페이지를 다시 로드하지 않고 변경된 모듈만 업데이트
온디맨드(On-demand) 컴파일: 요청 시에만 파일을 변환하여, 불필요한 빌드 시간을 줄임
Vite의 이러한 특징은 개발 생산성을 높이고, 빠른 피드백 루프(Fast Feedback Loop)를 가능하게 한다.