[G1-Sync] Manual knowledge update
This commit is contained in:
@@ -0,0 +1,397 @@
|
||||
---
|
||||
id: frontend-turbopack-rspack
|
||||
title: Modern Bundlers — Turbopack / Rspack / esbuild / Bun
|
||||
category: Coding
|
||||
status: draft
|
||||
source_trust_level: B
|
||||
verification_status: conceptual
|
||||
created_at: 2026-05-09
|
||||
updated_at: 2026-05-09
|
||||
tags: [frontend, build, vibe-coding]
|
||||
tech_stack: { language: "TS / Rust", applicable_to: ["Frontend"] }
|
||||
applied_in: []
|
||||
aliases: [Turbopack, Rspack, esbuild, swc, Bun bundler, Lightning CSS, Parcel 2]
|
||||
---
|
||||
|
||||
# Modern Bundlers
|
||||
|
||||
> Webpack 보다 10-100x 빠른 native bundler. **Turbopack (Next), Rspack, esbuild, swc, Bun**. Rust / Go 가 build 시간 ↓.
|
||||
|
||||
## 📖 핵심 개념
|
||||
- JS bundler 가 JS = 느림.
|
||||
- Rust / Go = 10x+ 빠름.
|
||||
- HMR < 100ms.
|
||||
- Webpack-compatible plugin (Rspack).
|
||||
|
||||
## 💻 코드 패턴
|
||||
|
||||
### Turbopack (Next.js 14+)
|
||||
```bash
|
||||
next dev --turbo
|
||||
```
|
||||
|
||||
```js
|
||||
// next.config.js
|
||||
module.exports = {
|
||||
experimental: {
|
||||
turbo: {
|
||||
rules: {
|
||||
'*.svg': { loaders: ['@svgr/webpack'], as: '*.js' },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
→ Webpack 대안. dev / production. Next 친화.
|
||||
|
||||
### Rspack (Webpack 호환)
|
||||
```js
|
||||
// rspack.config.js
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
entry: './src/index.tsx',
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{ test: /\.tsx?$/, use: 'builtin:swc-loader' },
|
||||
{ test: /\.css$/, use: ['style-loader', 'css-loader'] },
|
||||
],
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
→ Webpack config 거의 그대로. Rust = 10x 빠름.
|
||||
|
||||
### esbuild (가장 빠름)
|
||||
```js
|
||||
// build.js
|
||||
import * as esbuild from 'esbuild';
|
||||
|
||||
await esbuild.build({
|
||||
entryPoints: ['src/index.tsx'],
|
||||
bundle: true,
|
||||
outfile: 'dist/bundle.js',
|
||||
format: 'esm',
|
||||
target: 'es2020',
|
||||
minify: true,
|
||||
sourcemap: true,
|
||||
});
|
||||
```
|
||||
|
||||
```bash
|
||||
# CLI
|
||||
esbuild src/index.ts --bundle --outfile=dist/out.js
|
||||
```
|
||||
|
||||
→ Go. 100x 빠른. Tree-shake / minify 약함.
|
||||
|
||||
### Vite (esbuild dev + Rollup prod)
|
||||
```js
|
||||
// vite.config.ts
|
||||
import { defineConfig } from 'vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
build: {
|
||||
target: 'es2020',
|
||||
rollupOptions: {
|
||||
output: { manualChunks: { vendor: ['react', 'react-dom'] } },
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
→ Dev = esbuild + native ESM (instant). Prod = Rollup (optimize).
|
||||
|
||||
### Bun bundler
|
||||
```bash
|
||||
bun build src/index.ts --outfile=dist/out.js --target=browser
|
||||
```
|
||||
|
||||
```ts
|
||||
// JS API
|
||||
await Bun.build({
|
||||
entrypoints: ['src/index.ts'],
|
||||
outdir: 'dist',
|
||||
target: 'browser',
|
||||
minify: true,
|
||||
});
|
||||
```
|
||||
|
||||
→ Bun runtime + bundler. 빠름. Plugin ecosystem 작음.
|
||||
|
||||
### swc (transformer, not bundler)
|
||||
```js
|
||||
// .swcrc
|
||||
{
|
||||
"jsc": {
|
||||
"parser": { "syntax": "typescript", "tsx": true },
|
||||
"target": "es2020",
|
||||
"transform": { "react": { "runtime": "automatic" } }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
swc src -d dist
|
||||
```
|
||||
|
||||
→ Babel 대체 (10x+ 빠름). Next / Vite / Rspack 가 사용.
|
||||
|
||||
### Lightning CSS
|
||||
```js
|
||||
import { transform } from 'lightningcss';
|
||||
|
||||
const { code } = transform({
|
||||
filename: 'main.css',
|
||||
code: Buffer.from(css),
|
||||
minify: true,
|
||||
targets: { chrome: 90 },
|
||||
});
|
||||
```
|
||||
|
||||
→ PostCSS 대체. Native CSS minify + autoprefixer + nesting.
|
||||
|
||||
### Vite + Lightning CSS
|
||||
```js
|
||||
export default defineConfig({
|
||||
css: {
|
||||
transformer: 'lightningcss',
|
||||
lightningcss: {
|
||||
targets: { chrome: 90, firefox: 90 },
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### Parcel 2
|
||||
```bash
|
||||
parcel src/index.html
|
||||
```
|
||||
|
||||
→ Zero-config. Type-safe + tree-shake. Webpack 보다 simple.
|
||||
|
||||
### Build performance 비교
|
||||
```
|
||||
프로젝트: 10k LOC TS, React.
|
||||
|
||||
Webpack 5: 25 sec
|
||||
esbuild: 0.5 sec
|
||||
Vite (dev): 0.3 sec (ESM)
|
||||
Vite (build): 8 sec (Rollup)
|
||||
Turbopack: 0.5 sec
|
||||
Rspack: 1.5 sec
|
||||
Bun: 0.4 sec
|
||||
```
|
||||
|
||||
→ esbuild / Bun 가 가장 빠름. Turbopack 가 dev 친화.
|
||||
|
||||
### HMR (Hot Module Replacement)
|
||||
```ts
|
||||
// Vite — automatic
|
||||
if (import.meta.hot) {
|
||||
import.meta.hot.accept((newModule) => {
|
||||
// ...
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
→ < 100ms. State 보존.
|
||||
|
||||
### Plugin ecosystem
|
||||
```
|
||||
Webpack: 가장 큰 (10년)
|
||||
Rspack: Webpack 호환 = 큰
|
||||
Vite: 중간 (Rollup plugin 호환)
|
||||
esbuild: 작음
|
||||
Turbopack: 작음 (Next 친화)
|
||||
Bun: 작음
|
||||
```
|
||||
|
||||
### Migration: Webpack → Rspack
|
||||
```bash
|
||||
npm rm webpack webpack-cli
|
||||
npm i @rspack/core @rspack/cli builtin:swc-loader
|
||||
```
|
||||
|
||||
```js
|
||||
// rspack.config.js (Webpack config 거의 동일)
|
||||
const config = require('./webpack.config');
|
||||
config.module.rules.forEach(r => {
|
||||
if (r.use === 'babel-loader') r.use = 'builtin:swc-loader';
|
||||
});
|
||||
module.exports = config;
|
||||
```
|
||||
|
||||
→ 1-2 시간 작업. 10x 빌드 빠름.
|
||||
|
||||
### Code splitting
|
||||
```ts
|
||||
// Dynamic import (모든 bundler 지원)
|
||||
const Module = await import('./heavy-module');
|
||||
```
|
||||
|
||||
```js
|
||||
// Manual chunks (Vite / Rollup)
|
||||
{
|
||||
build: {
|
||||
rollupOptions: {
|
||||
output: {
|
||||
manualChunks: {
|
||||
react: ['react', 'react-dom'],
|
||||
ui: ['@mui/material'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Tree-shaking
|
||||
```ts
|
||||
// Side-effect free (package.json)
|
||||
{
|
||||
"sideEffects": false
|
||||
}
|
||||
|
||||
// 또는 specific
|
||||
"sideEffects": ["**/*.css"]
|
||||
```
|
||||
|
||||
→ Unused export 제거.
|
||||
|
||||
### ESM vs CJS
|
||||
```
|
||||
Modern: ESM (import / export)
|
||||
Legacy: CJS (require / module.exports)
|
||||
|
||||
Tree-shake = ESM 만.
|
||||
모든 modern bundler = ESM 우선.
|
||||
```
|
||||
|
||||
### Source map
|
||||
```js
|
||||
// Vite
|
||||
{ build: { sourcemap: true } }
|
||||
|
||||
// esbuild
|
||||
{ sourcemap: 'external' }
|
||||
|
||||
// Rspack
|
||||
{ devtool: 'source-map' }
|
||||
```
|
||||
|
||||
→ Production = `hidden-source-map` (서버 만).
|
||||
|
||||
### Bundle analyze
|
||||
```js
|
||||
// rollup-plugin-visualizer (Vite)
|
||||
import { visualizer } from 'rollup-plugin-visualizer';
|
||||
plugins: [visualizer()]
|
||||
|
||||
// Rspack
|
||||
import { BundleAnalyzerPlugin } from '@rspack/plugin-bundle-analyzer';
|
||||
```
|
||||
|
||||
→ HTML 가 chunk size + dep tree.
|
||||
|
||||
### CSS-in-JS 의 문제
|
||||
```
|
||||
Emotion / styled-components 가 runtime cost.
|
||||
Modern: CSS Module + Lightning CSS / Vanilla Extract / Panda CSS / Tailwind.
|
||||
|
||||
→ Build-time CSS = 0 runtime cost.
|
||||
```
|
||||
|
||||
### Incremental build
|
||||
```
|
||||
Vite / Rspack / Turbopack:
|
||||
- 변경 file 만 rebuild
|
||||
- Cache disk 에 (memo)
|
||||
|
||||
→ Full rebuild 거의 X.
|
||||
```
|
||||
|
||||
### Production build 권장
|
||||
```
|
||||
Vite + Rollup: balance (안정 + 빠름)
|
||||
Rspack: Webpack 마이그레이션 부드러움
|
||||
Next + Turbopack: Next.js 친화
|
||||
esbuild: 빠름 + 작은 plugin
|
||||
Bun: 가장 빠름, ecosystem 작음
|
||||
```
|
||||
|
||||
### Watch mode
|
||||
```bash
|
||||
esbuild ... --watch
|
||||
vite # default watch
|
||||
rspack ... --watch
|
||||
bun build ... --watch
|
||||
```
|
||||
|
||||
→ < 100ms rebuild on save.
|
||||
|
||||
### Polyfill / browser target
|
||||
```js
|
||||
// Vite
|
||||
{ build: { target: ['chrome90', 'firefox90', 'safari14'] } }
|
||||
|
||||
// esbuild
|
||||
{ target: ['chrome90'] }
|
||||
|
||||
// Babel preset-env (Webpack)
|
||||
{ targets: '> 0.5%, last 2 versions' }
|
||||
```
|
||||
|
||||
### Dev server
|
||||
```
|
||||
Vite: HTTP/1.1 + ESM (instant)
|
||||
Webpack dev server: bundle (느림)
|
||||
Turbopack: incremental
|
||||
```
|
||||
|
||||
### Future
|
||||
```
|
||||
- Rolldown (Vite 의 Rust Rollup) — 2025+
|
||||
- Bun bundler 점진 성숙
|
||||
- Turbopack stable
|
||||
- swc 가 dominate compiler
|
||||
|
||||
→ Webpack 의 share 줄어듦.
|
||||
```
|
||||
|
||||
## 🤔 의사결정 기준
|
||||
| 상황 | 추천 |
|
||||
|---|---|
|
||||
| New React app | Vite |
|
||||
| New Next.js | Turbopack |
|
||||
| Webpack migrate | Rspack |
|
||||
| Library author | tsup (esbuild) / Vite |
|
||||
| Bun runtime | Bun bundler |
|
||||
| 큰 enterprise (legacy) | Rspack (Webpack 호환) |
|
||||
| Build speed 가 결정 | esbuild |
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Webpack 만**: 10x 느린 build.
|
||||
- **Babel + Webpack new project**: swc + Vite/Rspack.
|
||||
- **CommonJS lib**: tree-shake X.
|
||||
- **No code split**: 큰 main bundle.
|
||||
- **CSS-in-JS runtime**: hydration cost.
|
||||
- **Source map prod**: 노출.
|
||||
- **Bundle analyze 없음**: bloat 모름.
|
||||
|
||||
## 🤖 LLM 활용 힌트
|
||||
- Vite / Turbopack / Rspack 가 default.
|
||||
- esbuild + swc = 빠른 transformer.
|
||||
- Lightning CSS = PostCSS 대체.
|
||||
- 큰 codebase = Rspack (Webpack compat).
|
||||
|
||||
## 🔗 관련 문서
|
||||
- [[Frontend_Tailwind_Architecture]]
|
||||
- [[TS_Build_Bundler_Patterns]]
|
||||
- [[Perf_Bundle_Analysis]]
|
||||
Reference in New Issue
Block a user