프론트엔드에서 빌드와 번들링

우디(박연기)·2025년 5월 4일
30
post-thumbnail

Intro

우테코 react-module 미션을 진행하면서 npm build 명령어 실행시 아래 사진과 같이 dist 폴더에 다양한 파일들이 생긴다. 이번에는 npm build 시 어떤 과정이 일어나는지 알아 보고 아래 파일들이 어떤 것을 의미하는 지 알아보자 🧐

빌드란?

빌드란, 개발자가 작성한 코드를 실행 가능한 코드로 변환하는 과정이다. 예를 들어, React 프로젝트를 만든 경우 개발자는 .jsx, .tsx, .css 등의 파일을 사용해 개발한다. 하지만 브라우저는 이러한 파일들을 직접 이해하거나 실행할 수 없다. 따라서 Webpack, Vite, Parcel 같은 빌드 도구를 사용하여, 브라우저가 이해하고 실행할 수 있는 정적 파일로 변환해주는 과정이 필요하다.

npm run dev?

우리는 리액트를 개발하다 보면, npm run dev 등과 같은 명령어로 빌드 과정을 하지 않고도 리액트 앱을 실행하곤 한다. 빌드 과정을 거치지 않으면 브라우저가 이해하지 못한다고 했는데 왜 npm run dev를 입력했을 때는 브라우저에 리액트 앱이 실행될까?

npm run dev는 “개발 모드” 명령어다. 보통 내부적으로 Vite, Webpack Dev Server 같은 개발용 서버가 실행된다. 이 개발 서버는 개발자가 코드를 수정할 때마다 자동으로 즉시 빌드해서 브라우저에 적용해준다. 그래서 우리가 npm run build처럼 명시적으로 번들 파일을 생성하지 않아도, 개발 중에는 실시간으로 빌드된 결과를 사용하는 것이다.

빌드 과정

빌드에 대해 알아봤으니, 이제 빌드 과정에 대해 알아보자. 우리가 자주 사용하는 번들링 도구인 vite를 기준으로 알아보자.

1. 설정 로딩 → 2. 의존성 분석 → 3. 트랜스파일 → 4. 번들링
→ 5. 최적화 → 6. dist 폴더에 산출물 출력

vite는 위와 같은 과정으로 빌드를 수행한다.

  1. 설정 로딩
    • vite.config.ts 등 설정 파일을 불러와서 빌드 대상, 플러그인, 출력 방식, 경로 등을 확인한다.
  2. 의존성 분석
    • 프로젝트의 진입점(index.html, main.tsx 등)을 기준으로, import 문을 따라가며 모든 모듈과 파일을 추적한다. 이 과정에서 내부적으로 ES 모듈 트리를 만들고, 최종적으로 어떤 파일이 필요한지 파악한다.
  3. 트랜스파일
    • .ts, .tsx, .scss, .jsx 등 브라우저가 바로 이해할 수 없는 파일을 자바스크립트로 변환한다.
      • TypeScript → JavaScript
      • JSX → JS
      • SCSS → CSS
    • 이 단계에서 Babel, esbuild, PostCSS 같은 도구를 사용한다.
  4. 번들링
    • 각각의 모듈들을 하나 또는 여러 개의 파일로 합쳐서 묶습니다. 이 과정에서 중복된 코드 제거, 코드 분할, 최적화 등을 수행합니다.
  5. 최적화
    • Tree Shaking 및 Minification 수행
      • Tree Shaking: 사용되지 않는 코드 제거
      • Minification: 공백, 주석, 긴 변수명을 줄여서 코드 크기를 최소화
  6. dist 폴더에 산출물 출력
    • 위 과정을 거쳐 만들어진 최종 산출물을 dist/ 폴더에 저장한다.
    • 예: index.html, assets/index-[hash].js, style-[hash].css 등이 생성된다.

.d.ts

빌드를 한 결과 .d.ts 파일이 생긴 것을 볼 수 있다. 이게 무엇일까?

.d.ts 파일은 TypeScript의 타입 선언 파일 (declaration file) 이다. JavaScript 코드에는 타입이 없기 때문에, TypeScript 사용자에게 타입 정보를 제공하기 위해 만들어진다.

해당 파일이 없으면 내 라이브러리를 다운 받고 사용하는 곳에서 props를 추론하지 못하고, 자동완성 기능을 제공하지 않는다. 그렇기 때문에 TypeScript로 만든 라이브러리의 경우 .d.ts 파일이 필요하다.

그러면 어떻게 .d.ts를 만들까?

tsconfig.jsondeclaration: true가 설정되어 있으면, TypeScript는 .js 파일과 함께 .d.ts 파일도 생성한다

{
  "compilerOptions": {
    "declaration": true,
  }
}

위와 같이 설정하면, 기본적으로 모든 TypeScript 파일에 대해 .d.ts 파일을 생성한다. 하지만 export가 되어 있지 않는 코드는 타입 정의에서 빠지게 된다.

또한 tsconfig.jsoninclude, exclude 설정에 따라, .d.ts 파일을 만들지 안 만들지를 결정한다.

{
  "include": ["src/lib"],
  "exclude": ["src/test"]
}

위와 같이 작성하면 src/lib 아래의 파일만 .d.ts 파일을 만들게 된다.

즉,

  • include어떤 파일을 컴파일할지 결정
  • exclude무시할 폴더나 파일을 지정

만약 둘 다 함께 설정하면 excludeinclude보다 우선 적용된다.

index.js 와 index.umd.cjs

.d.ts에 대해서는 알아봤다. 그러면 index.jsindex.umd.cjs는 무엇일까?

index.jsindex.umd.js 는 자바스크립트 코드가 번들링된 결과물이다. 실제로 배포를 할 때는 해당 파일을 배포하여 사용자가 사용할 수 있게 한다.

결국 index.js가 실제 실행 파일이고, .d.ts 파일은 타입 선언 파일로, 라이브러리를 사용하는 쪽에서 자동 완성, 타입 추론, 타입 안전성 등을 제공한다.

index.umd.js vs index.umd.cjs

빌드된 결과물이 어떤 모듈 시스템을 따르는지에 따라 구분된 파일이다.

index.js

  • ES Module (ESM) 형식이다.
  • import / export 구문을 사용하는 모듈 시스템을 따른다.
  • 최신 브라우저, Node.js 등에서 공식적으로 지원한다.

index.umd.cjs

  • UMD (Universal Module Definition) 형식이다.
  • CommonJS + AMD + 전역변수 등 다양한 환경에서 사용할 수 있도록 만든 범용적인 포맷이다.
  • 주로 브라우저에서
  • 라이브러리를 CDN 등으로 배포할 때 사용된다.

그렇기 때문에 두 파일을 모두 배포 해야지, 어느 환경에서든 범용적으로 사용할 수 있는 라이브러리가 된다.

하지만 그렇게 하기 위해서 아래 처럼 package.json 파일에 따로 설정해줘야 한다.

"main": "dist/index.umd.cjs", // CommonJS 환경에서 진입점이 되는 파일
"module": "dist/index.js", // ESM(ES Module) 환경의 진입점

마지막으로 번들링에 얕게 대해서 알아보자….


번들링?

영어 bundle 은 묶음이라는 뜻을 가진다. 즉 파일을 번들링한다는 여러개의 파일을 하나로 묶는다는 뜻이다. 번들링은 빌드 과정중 하나로 번들링된 파일을 배포하거나 브라우저에서 실행하곤 한다.

번들링을 왜 할까?

  1. 파일 크기 문제 해결
    • 번들링은 여러 개의 자바스크립트 파일을 하나로 합치고, 필요에 따라 압축(minify)하는 과정이다. 이 과정을 통해 파일 크기가 작아지고, 로딩 속도와 실행 속도가 향상된다. gzip과 같은 압축 방식과 함께 사용되면 브라우저로 전송되는 자바스크립트 코드 양을 크게 줄일 수 있어 네트워크 비용도 절감된다.
  2. 서버 요청이 적어진다.
    • 파일이 여러 개로 나뉘어 있으면 브라우저가 각 파일을 별도로 요청해야 한다. 예를들어, JS 파일이 100개라면, 최소 100번의 HTTP 요청이 발생한다. 하지만, 번들링을 하면 하나의 파일(또는 소수의 청크 파일)로 줄일 수 있어, 서버 요청 수가 획기적으로 줄어든다.
  3. 브라우저 호환성 향상
    • 최신 자바스크립트 문법은 오래된 브라우저에서 작동하지 않을 수 있다. 번들링 도구는 Babel과 같은 트랜스파일러와 함께 사용되어, 최신 코드를 구형 브라우저에서도 동작하도록 변환해준다. 이를 통해 더 넓은 사용자층을 지원할 수 있다.
  4. 파일 단위의 모듈 관리
    • ES6 이전의 자바스크립트는 전역 범위(global scope)를 기본으로 했기 때문에, 스크립트 간 변수 충돌 문제가 자주 발생했다. 번들링 도구는 각 모듈을 독립적인 스코프로 감싸기 때문에, 전역 변수 충돌 없이 안전하게 파일을 분리하고 관리할 수 있다. 또한, 의존성 그래프를 분석하여 사용되는 코드만 추출(tree-shaking)하는 등의 최적화도 가능해진다.

출처

https://parodev.tistory.com/58

https://velog.io/@jwo0o0/Web-프론트엔드에서-번들링이란-Webpack

profile
프론트엔드 개발하는 사람

2개의 댓글

comment-user-thumbnail
2025년 5월 4일

우디 덕분에 빌드 마스터 가능할 것 같네요! 좋은데요? 👍

답글 달기
comment-user-thumbnail
2025년 5월 16일

좋은 글 감사합니다~

답글 달기