번들링
1. 개요
1. 개요
번들링은 여러 개의 소프트웨어 모듈이나 파일을 하나 또는 적은 수의 파일로 묶는 과정이다. 이는 주로 프론트엔드 개발에서 웹 애플리케이션의 자원(JavaScript, CSS, 이미지 등)을 최적화하기 위해 사용된다. 번들링의 핵심 목적은 네트워크 요청 수를 줄이고 로딩 성능을 향상시키는 데 있다.
번들링은 빌드 도구의 핵심 과정으로, Webpack, Rollup, Parcel, Vite 등이 대표적인 번들러이다. 이러한 도구들은 코드 결합, 의존성 관리, 코드 분할, 트리 쉐이킹, 로더 및 플러그인 시스템과 같은 주요 기능을 제공하여 개발 효율성과 애플리케이션 성능을 높인다.
번들링 과정은 성능 최적화의 중요한 부분을 차지한다. 모듈화된 수많은 파일을 그대로 배포하면 브라우저가 각 파일을 개별적으로 요청해야 하므로 네트워크 지연이 발생할 수 있다. 번들러는 이러한 파일들을 분석하여 의존 관계를 파악하고, 최종적으로 최적화된 하나의 번들 파일(또는 청크)로 생성한다.
이를 통해 개발자는 모듈 단위로 코드를 작성하는 유연성을 유지하면서도, 사용자에게는 빠르게 로드되는 애플리케이션을 제공할 수 있다. 따라서 번들링은 현대 웹 개발에서 필수적인 빌드 및 배포 단계로 자리 잡았다.
2. 목적과 필요성
2. 목적과 필요성
번들링의 주요 목적은 웹 애플리케이션의 성능을 개선하는 것이다. 현대의 복잡한 프론트엔드 개발은 수십, 수백 개의 자바스크립트 모듈, CSS 파일, 이미지, 폰트 등 다양한 자원으로 구성된다. 브라우저가 이러한 각각의 파일을 개별적으로 다운로드하려면 많은 네트워크 요청이 발생하며, 이는 페이지 로딩 속도를 현저히 저하시킨다. 번들링은 이러한 여러 파일들을 하나 또는 적은 수의 번들 파일로 묶어 네트워크 요청 횟수를 획기적으로 줄임으로써 초기 로딩 시간을 단축한다.
번들링의 필요성은 모듈화된 개발 방식과 밀접하게 연결되어 있다. 개발자는 코드의 재사용성과 유지보수성을 높이기 위해 기능별로 모듈을 분리하여 작성한다. 그러나 브라우저의 역사적 한계로 인해, ES 모듈과 같은 현대적 모듈 시스템을 모든 환경에서 바로 사용할 수 없었다. 번들러는 서로 다른 모듈 형식(CommonJS, AMD, ES 모듈 등)을 이해하고 이들 간의 의존성을 해결하여 브라우저가 실행할 수 있는 형태로 변환하는 중요한 역할을 수행한다. 이는 개발 편의성과 프로덕션 호환성을 동시에 보장한다.
또한, 번들링은 단순한 파일 결합을 넘어 다양한 최적화 작업의 기반이 된다. 번들링 과정에서 트리 쉐이킹을 통해 사용되지 않는 코드를 제거하거나, 코드 분할을 통해 필요한 시점에만 특정 코드를 로드할 수 있게 하며, 파일 압축을 통해 전송 크기를 줄일 수 있다. 이러한 최적화는 특히 모바일 환경이나 느린 네트워크에서 사용자 경험을 크게 향상시킨다. 따라서 번들링은 현대 웹 개발의 빌드 도구 파이프라인에서 필수적인 단계로 자리 잡았다.
3. 주요 번들러
3. 주요 번들러
3.1. Webpack
3.1. Webpack
웹팩(Webpack)은 현대 프론트엔드 개발에서 가장 널리 사용되는 모듈 번들러이다. 주로 자바스크립트 모듈을 번들링하는 데 사용되지만, 로더를 통해 CSS, 이미지, 폰트 등 다양한 정적 자원도 처리할 수 있다. 웹팩의 핵심 철학은 모든 것을 모듈로 간주하는 것이며, 이를 통해 복잡한 애플리케이션의 의존성을 효과적으로 관리한다.
웹팩은 강력한 설정 기반의 도구로, webpack.config.js 파일을 통해 진입점, 출력 경로, 로더, 플러그인 등 번들링 과정의 거의 모든 측면을 세밀하게 제어할 수 있다. 이는 초기 학습 곡선이 존재하는 이유이기도 하지만, 동시에 매우 유연하고 확장 가능한 생태계를 구축하는 기반이 되었다. 수많은 서드파티 로더와 플러그인이 존재하여 다양한 개발 요구사항을 충족시킨다.
주요 기능으로는 코드 분할을 통한 초기 로딩 성능 최적화, 트리 쉐이킹을 통한 사용하지 않는 코드 제거, 개발 편의성을 위한 핫 모듈 교체 지원 등이 있다. 특히 대규모 싱글 페이지 애플리케이션 개발에 적합하며, 리액트, 뷰, 앵귤러 등 주요 프론트엔드 프레임워크의 공식 빌드 도구로 채택되거나 널리 함께 사용된다.
웹팩은 강력한 기능과 성숙한 생태계를 바탕으로 프론트엔드 빌드 도구의 사실상의 표준 역할을 해왔으나, 상대적으로 복잡한 설정과 느린 빌드 속도가 단점으로 지적되어 왔다. 이러한 문제를 해결하기 위해 등장한 Vite나 Parcel 같은 새로운 도구들에 비해, 웹팩은 여전히 가장 많은 레거시 프로젝트와 대규모 엔터프라이즈 환경에서 사용되고 있다.
3.2. Rollup
3.2. Rollup
Rollup은 자바스크립트 모듈 번들러로, 특히 라이브러리나 프레임워크와 같은 배포용 패키지를 제작하는 데 적합한 도구이다. ES6 모듈 문법을 기본으로 지원하며, 트리 쉐이킹을 통해 사용하지 않는 코드를 효과적으로 제거하여 최종 번들 크기를 줄이는 데 강점을 보인다. 이러한 특징으로 인해 React와 Vue.js 같은 주요 프론트엔드 프레임워크의 핵심 빌드 도구로 널리 사용되고 있다.
Rollup의 설계 철학은 단순성과 효율성에 있다. 복잡한 설정보다는 명확한 API와 예측 가능한 동작을 중시하며, 플러그인 시스템을 통해 필요한 기능을 확장할 수 있다. 이는 웹팩과 같은 다른 번들러에 비해 상대적으로 간결한 설정 파일을 가능하게 한다. 또한, CommonJS 모듈을 ES6 모듈로 변환하는 기능을 내장하고 있어, 기존 노드 생태계의 패키지와도 호환성을 유지한다.
주요 구성 요소로는 입력 파일을 지정하는 input, 출력 형식과 경로를 정의하는 output, 그리고 변환 및 최적화 작업을 처리하는 plugins가 있다. 출력 형식은 ES 모듈, CommonJS, IIFE 등 다양한 모듈 시스템을 지원하여 라이브러리를 여러 환경에 배포하는 데 유연성을 제공한다. Rollup은 기본적으로 자바스크립트와 타입스크립트 파일을 처리할 수 있으며, CSS나 이미지 같은 자원은 공식 또는 서드파티 플러그인을 통해 번들에 포함시킬 수 있다.
Rollup은 애플리케이션 번들링에도 사용될 수 있지만, 대규모 싱글 페이지 애플리케이션보다는 라이브러리 빌드에 더 최적화되어 있다는 평가를 받는다. 코드 분할과 핫 모듈 교체 같은 고급 기능은 플러그인을 통해 구현 가능하지만, 웹팩이나 Vite에 비해 기본 지원이 부족할 수 있다. 따라서 프로젝트의 성격과 요구사항에 따라 적절한 번들러를 선택하는 것이 중요하다.
3.3. Parcel
3.3. Parcel
Parcel은 프론트엔드 개발에서 사용되는 빌드 도구이자 번들러이다. Webpack이나 Rollup과 같은 다른 도구들과 달리, Parcel은 별도의 설정 파일 없이도 바로 사용할 수 있는 '제로 컨피규레이션' 철학을 지향한다. 개발자는 HTML, JavaScript, CSS 파일만 준비하면 Parcel이 자동으로 의존성을 분석하고 필요한 변환 작업을 수행하여 최적화된 번들을 생성한다. 이는 초보자에게 진입 장벽을 낮추고 빠른 프로토타이핑에 유리하다.
Parcel의 핵심 특징은 다중 코어 프로세싱을 활용한 빠른 빌드 속도와 내장된 다양한 변환기이다. Babel, PostCSS, TypeScript와 같은 도구를 별도로 설정하지 않아도 기본적으로 지원하며, 이미지, 폰트 같은 자산 파일들도 자동으로 처리한다. 또한, 핫 모듈 리플레이스먼트 기능을 내장하여 코드 수정 시 페이지를 새로 고치지 않고도 변경 사항을 실시간으로 브라우저에 반영할 수 있어 개발자 경험을 향상시킨다.
Parcel은 코드 분할과 트리 쉐이킹 같은 최적화 기능도 기본적으로 제공한다. 동적 import() 구문을 사용하면 자동으로 코드를 분할하고, 사용하지 않는 코드는 번들에서 제거하여 최종 번들 크기를 줄인다. 이러한 자동화된 최적화는 복잡한 설정 없이도 웹 애플리케이션의 로딩 성능을 개선하는 데 도움을 준다.
3.4. Vite
3.4. Vite
Vite는 프론트엔드 개발을 위한 차세대 빌드 도구이다. 기존 번들러들과는 달리, 네이티브 ES 모듈을 기반으로 하여 개발 서버를 매우 빠르게 시작하고 핫 모듈 교체를 지원한다. 프로덕션 빌드 시에는 Rollup을 사용하여 효율적인 번들링을 수행한다. 이러한 설계로 인해 대규모 프로젝트에서도 빠른 개발 경험을 제공하는 것이 주요 특징이다.
Vite의 핵심은 개발 서버와 빌드 과정의 분리에 있다. 개발 중에는 브라우저가 ES 모듈을 직접 요청하고, Vite는 요청에 따라 필요한 모듈만 변환하여 제공한다. 이는 전체 애플리케이션을 미리 번들링할 필요가 없어 서버 시작 시간이 거의 즉각적이며, 코드 수정 시에도 변경된 모듈만 갱신하면 되므로 반응 속도가 빠르다. 프로덕션 배포를 위해서는 Rollup을 통해 전통적인 방식의 최적화된 번들을 생성한다.
Vite는 Vue.js 창시자에 의해 만들어졌지만, 현재는 React, Preact, Svelte 등 다양한 프레임워크를 공식적으로 지원한다. 또한 풍부한 플러그인 생태계와 간결한 설정을 통해 사용자 친화적인 환경을 제공한다. TypeScript, CSS 전처리기, 정적 자원 처리 등 현대적인 웹 개발에 필요한 기능들을 기본적으로 포함하고 있다.
특징 | 설명 |
|---|---|
개발 서버 속도 | 네이티브 ES 모듈을 활용하여 즉시 시작 |
핫 모듈 교체 | 변경된 모듈만 빠르게 갱신 |
프로덕션 빌드 | Rollup을 기반으로 한 효율적인 번들링 |
프레임워크 지원 | Vue, React, Svelte 등 다수 지원 |
설정 | 거의 제로 컨피그에 가까운 간결한 설정 |
4. 작동 방식
4. 작동 방식
4.1. 의존성 그래프
4.1. 의존성 그래프
번들링 과정의 핵심은 의존성 그래프를 구성하는 것이다. 번들러는 프로젝트의 진입점 파일(예: index.js 또는 main.js)부터 시작하여, 해당 파일에서 import나 require 문을 통해 참조하는 모든 모듈과 파일을 재귀적으로 탐색한다. 이 과정에서 각 모듈 간의 관계는 노드와 간선으로 표현되는 그래프 구조로 맵핑되며, 이를 의존성 그래프라고 부른다.
의존성 그래프는 번들러가 전체 애플리케이션의 구조와 모듈 간의 연결 관계를 이해하는 데 필수적인 청사진 역할을 한다. 이 그래프를 통해 번들러는 어떤 모듈이 어떤 순서로 로드되어야 하는지, 어떤 모듈이 다른 모듈에 의존하는지, 그리고 어떤 모듈이 전혀 사용되지 않는지(즉, 트리 쉐이킹 대상인지)를 정확히 파악할 수 있다. 이는 단순히 파일을 합치는 것을 넘어, 최종 번들 결과물의 크기와 성능을 결정하는 기초가 된다.
의존성 그래프를 구성한 후, 번들러는 이 그래프를 순회하며 각 모듈의 코드를 분석하고 변환한다. 이 단계에서 로더나 플러그인이 적용되어 JavaScript 외에도 CSS, 이미지, 폰트 등 다양한 자원을 처리할 수 있다. 최종적으로 그래프의 모든 노드(모듈)는 올바른 순서로 평가되고 실행될 수 있도록 하나의 실행 가능한 번들 파일로 병합되거나, 코드 분할 전략에 따라 여러 청크 파일로 나누어진다.
의존성 그래프의 정확성은 번들링 결과의 신뢰성을 보장한다. 잘못 구성된 그래프는 런타임 오류나 불필요한 코드의 포함을 초래할 수 있다. 따라서 Webpack이나 Rollup과 같은 현대 번들러는 정교한 정적 분석 기법을 사용하여 가능한 한 정확한 의존성 그래프를 구축하고, 이를 기반으로 다양한 성능 최적화를 수행한다.
4.2. 로더(Loader)와 플러그인(Plugin)
4.2. 로더(Loader)와 플러그인(Plugin)
번들러의 핵심 확장 메커니즘은 로더와 플러그인 시스템이다. 이 두 요소는 번들러가 다양한 파일 형식을 처리하고, 빌드 과정을 세밀하게 제어하며, 복잡한 최적화 작업을 수행할 수 있게 해준다.
로더는 번들러가 자바스크립트 이외의 파일, 예를 들어 CSS, 이미지, 폰트, 또는 타입스크립트 파일 등을 처리할 수 있도록 변환 작업을 담당한다. 각 로더는 특정 파일 확장자에 매핑되어, 해당 파일을 번들러가 이해하고 처리 가능한 모듈로 변환한다. 예를 들어, CSS 파일을 처리하는 로더는 CSS 코드를 DOM에 주입할 수 있는 자바스크립트 문자열로 변환하거나, 별도의 CSS 파일로 추출하는 작업을 수행한다. 로더는 체인으로 연결되어 순차적으로 적용될 수 있으며, 이를 통해 하나의 파일에 대해 여러 단계의 변환을 거칠 수 있다.
반면, 플러그인은 번들링 과정 전반에 걸쳐 더 넓은 범위의 작업을 수행한다. 로더가 개별 파일의 변환에 집중한다면, 플러그인은 번들 생성의 라이프사이클 훅에 접근하여 번들 최적화, 에셋 관리, 환경 변수 주입 등 다양한 부가 기능을 제공한다. 대표적인 플러그인의 역할로는 생성된 번들 코드의 압축, 트리 쉐이킹 적용, HTML 템플릿에 자동으로 번들 파일을 연결하는 HTML 웹팩 플러그인 생성, 개발 서버 실행 등이 있다. 플러그인 시스템은 번들러의 기능을 무한히 확장할 수 있는 기반을 마련한다.
구분 | 주요 역할 | 적용 시점 | 예시 |
|---|---|---|---|
로더 | 개별 파일 변환/트랜스파일링 | 모듈 해석 및 의존성 그래프 생성 단계 |
|
플러그인 | 번들 전체에 대한 부가 작업 및 최적화 | 번들링 과정의 다양한 라이프사이클 훅 |
|
요약하면, 로더는 '번들에 포함될 각 모듈의 내용을 변환하는 변환기'라면, 플러그인은 '변환된 모듈들을 묶는 번들링 과정 자체를 제어하고 개선하는 도구'라고 볼 수 있다. 현대적인 프론트엔드 개발에서는 이 두 시스템을 조합하여 복잡한 프로젝트의 빌드 파이프라인을 구성한다.
5. 번들링 최적화
5. 번들링 최적화
5.1. 코드 분할(Code Splitting)
5.1. 코드 분할(Code Splitting)
코드 분할은 번들링 과정에서 애플리케이션의 코드를 여러 개의 번들로 나누는 최적화 기법이다. 초기 로딩 시 필요한 최소한의 코드만 먼저 다운로드하고, 나머지 코드는 필요할 때 지연 로딩하는 방식을 통해 웹 애플리케이션의 초기 로딩 속도를 크게 향상시킨다. 이는 특히 SPA와 같이 규모가 큰 프론트엔드 애플리케이션에서 필수적인 성능 최적화 기술로 자리 잡았다.
코드 분할은 크게 두 가지 방식으로 구현된다. 첫째는 진입점 분할로, 웹팩 등의 번들러 설정에서 여러 진입점을 지정하여 각각 별도의 번들을 생성하는 방법이다. 둘째는 동적 임포트를 활용하는 방식으로, 자바스크립트의 import() 문법을 사용하여 런타임에 특정 모듈을 비동기적으로 불러오는 것이다. 이 방식을 통해 라우트 기반 분할이나 컴포넌트 기반 분할을 구현할 수 있다.
분할 방식 | 설명 | 구현 방법 |
|---|---|---|
진입점 분할 | 여러 개의 진입 파일을 기준으로 번들을 분리 | 번들러 설정에서 |
동적 임포트 | 런타임에 조건에 따라 모듈을 비동기 로딩 |
|
이 기법을 효과적으로 적용하면 사용자가 첫 화면을 빠르게 볼 수 있고, 불필요한 코드 다운로드를 방지하여 전체적인 사용자 경험을 개선할 수 있다. 리액트, 뷰, 앵귤러 등의 현대 자바스크립트 라이브러리와 프레임워크는 코드 분할을 내부적으로 지원하거나 쉽게 적용할 수 있는 API를 제공한다.
5.2. 트리 쉐이킹(Tree Shaking)
5.2. 트리 쉐이킹(Tree Shaking)
트리 쉐이킹은 번들링 과정에서 사용되지 않는 코드를 최종 번들 파일에서 제거하는 데드 코드 제거 최적화 기법이다. 이 용어는 나무를 흔들어 마른 잎을 떨어뜨리는 것에 비유하여, 애플리케이션에 실제로 필요한 코드만을 남기고 불필요한 코드를 제거하는 과정을 의미한다. 이 기법은 특히 ES6 모듈 시스템의 정적 구조 분석을 기반으로 하며, JavaScript 라이브러리나 애플리케이션의 번들 크기를 효과적으로 줄여준다.
트리 쉐이킹이 효과적으로 동작하기 위해서는 모듈이 ES6 모듈의 import와 export 문법을 사용하여 작성되어야 한다. 이는 CommonJS와 같은 동적 모듈 시스템에서는 모듈의 의존 관계를 빌드 타임에 정확히 분석하기 어렵기 때문이다. 번들러는 애플리케이션의 진입점부터 시작하여 모든 import 경로를 따라가며 의존성 그래프를 생성하고, 실제로 사용되는 export만을 추적한다. 이 과정에서 그래프에 연결되지 않은, 즉 어떤 모듈에서도 참조하지 않는 함수, 클래스, 변수 등의 코드는 최종 번들에서 제외된다.
대표적인 번들러인 Webpack과 Rollup은 트리 쉐이킹을 기본적으로 지원한다. Webpack은 프로덕션 모드로 빌드할 때 자동으로 트리 쉐이킹을 수행하며, Rollup은 설계 초기부터 효율적인 트리 쉐이킹을 핵심 목표로 삼았다. 최신 도구인 Vite 또한 내부 번들러로 Rollup을 사용하거나 esbuild를 활용하여 이 기능을 제공한다. 개발자는 패키지 관리자를 통해 설치한 서드파티 라이브러리에서도 불필요한 코드가 포함되지 않도록, 라이브러리가 트리 쉐이킹에 친화적인 방식으로 배포되었는지 확인해야 한다.
트리 쉐이킹의 주요 장점은 최종 사용자가 다운로드해야 하는 JavaScript 코드의 양을 줄여 웹 페이지의 로딩 성능과 실행 속도를 개선한다는 점이다. 그러나 이 기법의 효과는 코드의 작성 방식과 모듈 구조에 크게 의존한다. 부작용이 있는 모듈 수준의 코드(예: 폴리필 또는 전역 스타일시트를 자동으로 적용하는 코드)가 포함된 경우, 이 코드가 사용되지 않더라도 제거되지 않을 수 있어 주의가 필요하다.
5.3. 압축(Minification)
5.3. 압축(Minification)
압축은 번들링 과정에서 생성된 번들 파일의 크기를 줄이기 위한 최적화 기법이다. 주로 자바스크립트, CSS, HTML 파일을 대상으로 수행되며, 배포 환경에서 애플리케이션의 로딩 속도를 높이고 대역폭 사용량을 줄이는 데 목적이 있다. 이 과정은 개발자가 작성한 가독성 높은 코드를 유지하면서, 실행에는 불필요한 공백, 주석, 긴 변수명 등을 제거하거나 단순화하여 파일을 경량화한다.
압축의 주요 작업은 다음과 같다. 공백과 줄바꿈을 제거하고, 주석을 삭제하며, 변수와 함수의 이름을 짧게 변경하는 등 코드의 구조를 변경하지 않는 범위 내에서 불필요한 문자를 최대한 제거한다. CSS의 경우 불필요한 세미콜론을 제거하거나 색상 값을 짧은 형식으로 변환하는 작업도 포함된다. 이러한 과정은 번들러의 플러그인이나 전용 도구를 통해 자동화되어 실행된다.
압축은 트리 쉐이킹이나 코드 분할과 같은 다른 최적화 기법과 함께 사용될 때 그 효과가 극대화된다. 예를 들어, Webpack에서는 TerserWebpackPlugin을, Rollup에서는 terser를 통합하여 압축을 수행한다. Vite는 프로덕션 빌드 시 기본적으로 코드를 압축한다. 이렇게 최종적으로 생성된 압축된 번들 파일은 네트워크를 통해 전송되는 시간을 단축시켜 사용자 경험을 개선한다.
압축 대상 파일 형식 | 주요 압축 작업 예시 |
|---|---|
JavaScript | 공백/주석 제거, 변수명 단축, 데드 코드 제거 |
CSS | 공백/주석 제거, 색상 코드 단축, 중복 규칙 병합 |
HTML | 공백/주석 제거, 불필요한 속성값 따옴표 생략 |
압축은 필수적인 빌드 단계이지만, 압축된 코드는 디버깅이 매우 어렵다는 단점이 있다. 따라서 대부분의 번들링 도구는 소스 맵 파일을 함께 생성하여, 배포된 압축 코드의 오류를 원본 소스 코드 위치에서 확인할 수 있도록 지원한다.
6. 장단점
6. 장단점
번들링은 프론트엔드 개발에서 애플리케이션 성능과 유지보수성을 크게 향상시키지만, 동시에 복잡성과 빌드 시간 증가라는 비용을 수반한다.
번들링의 주요 장점은 성능 최적화에 있다. 여러 개의 모듈과 자원을 하나 또는 소수의 파일로 묶음으로써 네트워크 요청 횟수를 획기적으로 줄인다. 이는 특히 HTTP/1.1 환경에서 페이지 로딩 속도를 크게 개선한다. 또한 트리 쉐이킹과 코드 분할 같은 기능을 통해 사용하지 않는 코드를 제거하고, 필요한 시점에 필요한 코드만 로드할 수 있어 최종 번들 크기를 최소화한다. 개발 측면에서는 CommonJS나 ES 모듈과 같은 모듈 시스템을 사용하여 코드를 체계적으로 구성할 수 있게 해주며, 바벨을 통한 트랜스파일링이나 Sass 컴파일과 같은 개발 편의 기능을 빌드 프로세스에 통합할 수 있다.
반면, 번들링은 복잡한 설정과 학습 곡선을 요구한다는 단점이 있다. Webpack과 같은 도구는 강력한 기능을 제공하지만, 그에 상응하는 복잡한 설정 파일이 필요하다. 이로 인해 초기 구축 및 디버깅에 시간이 소요될 수 있다. 또한, 모든 소스 코드를 분석하고 변환하는 과정에서 빌드 시간이 길어질 수 있으며, 대규모 프로젝트에서는 이 빌드 시간이 개발 생산성에 영향을 미칠 수 있다. 번들링된 결과물은 원본 소스 코드와 다르기 때문에, 디버깅 시 소스 맵에 의존해야 하는 번거로움이 발생할 수 있다.
요약하면, 번들링은 프로덕션 환경의 성능과 개발의 모듈화에는 필수적이지만, 도구의 복잡성과 빌드 오버헤드를 관리해야 하는 과제를 안고 있다. 프로젝트의 규모와 요구사항에 따라 Vite나 Parcel 같이 설정이 간편한 도구를 선택하거나, 코드 분할 전략을 세밀하게 구성하여 단점을 완화하는 것이 중요하다.
