Skip to content

Commit 6735b0c

Browse files
committed
♻️ Refactor manual chunk splitting for improved cache efficiency
1 parent 29913b6 commit 6735b0c

1 file changed

Lines changed: 40 additions & 22 deletions

File tree

vite.config.ts

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,47 @@ import { defineConfig, PluginOption } from 'vite';
44
import { VitePWA } from 'vite-plugin-pwa';
55
import tsconfigPaths from 'vite-tsconfig-paths';
66

7-
import { dependencies } from './package.json';
8-
9-
/** Filter out React-related dependencies from the list */
10-
const reactDeps = Object.keys(dependencies).filter(
11-
(key) => key === 'react' || key.startsWith('react-'),
12-
);
13-
147
/**
15-
* Generates custom chunks for Rollup or Vite based on the dependencies provided.
16-
* The 'vendor' chunk includes all React-related dependencies, while additional chunks
17-
* are created for each remaining dependency not already included in 'vendor'.
18-
* For more information on this approach, see the following article:
19-
* {@link https://sambitsahoo.com/blog/vite-code-splitting-that-works.html Referenced Code}
8+
* Vite(Rollup) 빌드 시 적용되는 커스텀 청크 분할(Code Splitting) 함수
9+
* * package.json의 전체 의존성을 무조건 청크로 만들 때 발생하던 "Generated an empty chunk" 경고를 방지하기 위해,
10+
* 빌드 파이프라인에 포함된 실제 `node_modules` 내부 모듈(`id`)만 대상으로 청크를 분리합니다.
11+
* 사용 목적과 업데이트 주기가 비슷한 패키지들을 하나의 그룹(chunk)으로 묶어 브라우저 캐시 효율을 극대화합니다.
12+
* * @param {string} id - Rollup이 현재 처리 중인 모듈의 절대 경로
13+
* @returns {string | undefined} 묶어줄 청크 이름. 명시되지 않은 모듈은 Rollup의 기본 분할 전략에 위임(`undefined`)
2014
*/
21-
const manualChunks = {
22-
// Include all React-related dependencies in a 'vendor' chunk
23-
vendor: reactDeps,
24-
// Generate additional chunks for remaining dependencies
25-
...Object.keys(dependencies).reduce((chunks, name) => {
26-
// Skip dependencies already included in 'vendor'
27-
if (!reactDeps.includes(name)) chunks[name] = [name];
28-
return chunks;
29-
}, {}),
15+
const manualChunks = (id: string): string | undefined => {
16+
if (!id.includes('node_modules')) return undefined;
17+
18+
// 경로 구분자 통일 (Windows 환경 호환성)
19+
const p = id.replace(/\\/g, '/');
20+
21+
// pnpm 심볼릭 링크 구조 대응: .../.pnpm/pkg@ver/node_modules/pkg/...
22+
const inPkg = (name: string) => p.includes(`/node_modules/${name}/`);
23+
24+
// 1. 코어 라이브러리 (React 생태계)
25+
if (inPkg('react') || inPkg('react-dom') || inPkg('scheduler'))
26+
return 'react';
27+
if (inPkg('react-router') || inPkg('react-router-dom')) return 'router';
28+
29+
// 2. UI 및 스타일링 (Chakra UI는 Emotion을 강하게 의존)
30+
if (inPkg('@chakra-ui') || inPkg('@emotion')) return 'chakra';
31+
32+
// 3. 상태 및 데이터 페칭
33+
if (inPkg('@tanstack/react-query') || inPkg('@tanstack/query-core'))
34+
return 'tanstack';
35+
if (inPkg('jotai')) return 'jotai';
36+
37+
// 4. 애니메이션 및 미디어
38+
if (inPkg('framer-motion')) return 'framer';
39+
if (inPkg('@lottiefiles') || inPkg('lottie-web')) return 'lottie';
40+
41+
// 5. 유틸리티 (HTTP 통신, 폼 검증, 날짜)
42+
if (inPkg('axios') || inPkg('qs')) return 'http';
43+
if (inPkg('yup') || inPkg('@hookform')) return 'form';
44+
if (inPkg('date-fns')) return 'date-fns';
45+
46+
// 6. 나머지는 Rollup의 기본 트리쉐이킹 및 청크 분할 알고리즘에 위임
47+
return undefined;
3048
};
3149

3250
// https://vitejs.dev/config/
@@ -53,7 +71,7 @@ export default defineConfig(({ mode }) => ({
5371
},
5472
}),
5573
tsconfigPaths(),
56-
visualizer() as unknown as PluginOption,
74+
mode === 'analyze' ? (visualizer() as unknown as PluginOption) : undefined,
5775

5876
/**
5977
* vite-plugin-pwa 플러그인으로 서비스 워커 스크립트 자동 등록

0 commit comments

Comments
 (0)