[G1-Sync] Manual knowledge update
This commit is contained in:
@@ -0,0 +1,405 @@
|
||||
---
|
||||
id: frontend-bun-lightning-patterns
|
||||
title: Bun Bundler / Lightning CSS / esbuild plugins
|
||||
category: Coding
|
||||
status: draft
|
||||
source_trust_level: B
|
||||
verification_status: conceptual
|
||||
created_at: 2026-05-09
|
||||
updated_at: 2026-05-09
|
||||
tags: [frontend, build, bun, vibe-coding]
|
||||
tech_stack: { language: "TS", applicable_to: ["Frontend"] }
|
||||
applied_in: []
|
||||
aliases: [Bun bundler, Lightning CSS, esbuild plugins, Bun.build, Vite plugin, build performance]
|
||||
---
|
||||
|
||||
# Bun / Lightning CSS / esbuild Plugins
|
||||
|
||||
> Modern build의 가장 빠른 부분. **Bun (JS runtime + bundler), Lightning CSS (Rust CSS), esbuild plugins**.
|
||||
|
||||
## 📖 핵심 개념
|
||||
- Bun: JS runtime + bundler + test + npm.
|
||||
- Lightning CSS: PostCSS 의 Rust 대체.
|
||||
- esbuild plugins: hook 을 plug.
|
||||
- 모든 native = 10-100x 빠름.
|
||||
|
||||
## 💻 코드 패턴
|
||||
|
||||
### Bun bundler (CLI)
|
||||
```bash
|
||||
bun build src/index.ts --outfile=dist/out.js --target=browser --minify
|
||||
```
|
||||
|
||||
### Bun bundler (JS API)
|
||||
```ts
|
||||
const result = await Bun.build({
|
||||
entrypoints: ['src/index.ts'],
|
||||
outdir: 'dist',
|
||||
target: 'browser',
|
||||
format: 'esm',
|
||||
minify: true,
|
||||
splitting: true,
|
||||
sourcemap: 'external',
|
||||
});
|
||||
|
||||
if (!result.success) {
|
||||
for (const m of result.logs) console.error(m);
|
||||
}
|
||||
```
|
||||
|
||||
### Bun runtime
|
||||
```ts
|
||||
// Hot reload
|
||||
bun --hot run server.ts
|
||||
|
||||
// SQLite native
|
||||
const db = new Bun.SQLite('app.db');
|
||||
db.query('SELECT * FROM users').all();
|
||||
|
||||
// Test
|
||||
bun test
|
||||
```
|
||||
|
||||
→ Node + npm + bundler + test 한 binary.
|
||||
|
||||
### Bun.serve
|
||||
```ts
|
||||
// 빠른 HTTP server
|
||||
Bun.serve({
|
||||
port: 3000,
|
||||
fetch(req) {
|
||||
return new Response('Hello');
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
→ Hono / Express 의 alternative. 빠름.
|
||||
|
||||
### Bun shell
|
||||
```ts
|
||||
import { $ } from 'bun';
|
||||
|
||||
await $`ls -la`;
|
||||
const r = await $`echo hello`.text();
|
||||
```
|
||||
|
||||
→ Cross-platform shell.
|
||||
|
||||
### Lightning CSS (Rust CSS)
|
||||
```bash
|
||||
yarn add -D lightningcss
|
||||
```
|
||||
|
||||
```ts
|
||||
import { transform, bundle } from 'lightningcss';
|
||||
|
||||
const { code, map } = transform({
|
||||
filename: 'main.css',
|
||||
code: Buffer.from(css),
|
||||
minify: true,
|
||||
sourceMap: true,
|
||||
targets: {
|
||||
chrome: 90 << 16,
|
||||
firefox: 90 << 16,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
→ PostCSS + autoprefixer + minify + nesting.
|
||||
|
||||
### Vite + Lightning CSS
|
||||
```js
|
||||
export default defineConfig({
|
||||
css: {
|
||||
transformer: 'lightningcss',
|
||||
lightningcss: {
|
||||
targets: { chrome: 90 },
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### Tailwind 4 + Lightning CSS
|
||||
```
|
||||
Tailwind v4 가 Lightning CSS 사용 (Rust 기반).
|
||||
- 100x 빠른 build.
|
||||
- CSS-native (no JS config).
|
||||
```
|
||||
|
||||
### CSS nesting (native)
|
||||
```css
|
||||
/* 모던 native nesting */
|
||||
.card {
|
||||
padding: 16px;
|
||||
|
||||
& h2 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: #eee;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
→ Lightning CSS 가 transform (구 browser).
|
||||
|
||||
### esbuild plugin 작성
|
||||
```ts
|
||||
import { build, Plugin } from 'esbuild';
|
||||
|
||||
const myPlugin: Plugin = {
|
||||
name: 'my-plugin',
|
||||
setup(build) {
|
||||
// Resolve hook
|
||||
build.onResolve({ filter: /\.json$/ }, args => ({
|
||||
path: args.path,
|
||||
namespace: 'json',
|
||||
}));
|
||||
|
||||
// Load hook
|
||||
build.onLoad({ filter: /.*/, namespace: 'json' }, async (args) => {
|
||||
const text = await fs.promises.readFile(args.path, 'utf8');
|
||||
return {
|
||||
contents: `export default ${text}`,
|
||||
loader: 'js',
|
||||
};
|
||||
});
|
||||
|
||||
// End hook
|
||||
build.onEnd((result) => {
|
||||
console.log(`Built ${result.outputFiles?.length}`);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
await build({
|
||||
entryPoints: ['index.ts'],
|
||||
bundle: true,
|
||||
outfile: 'out.js',
|
||||
plugins: [myPlugin],
|
||||
});
|
||||
```
|
||||
|
||||
### Common esbuild plugins
|
||||
```
|
||||
- esbuild-plugin-svelte
|
||||
- esbuild-plugin-vue
|
||||
- esbuild-plugin-postcss
|
||||
- esbuild-plugin-svgr
|
||||
- esbuild-plugin-glob
|
||||
```
|
||||
|
||||
### Vite plugin (Rollup 기반)
|
||||
```ts
|
||||
import type { Plugin } from 'vite';
|
||||
|
||||
export function myPlugin(): Plugin {
|
||||
return {
|
||||
name: 'my-plugin',
|
||||
|
||||
config(config) {
|
||||
// Modify config
|
||||
},
|
||||
|
||||
transform(code, id) {
|
||||
if (id.endsWith('.special')) {
|
||||
return { code: transform(code) };
|
||||
}
|
||||
},
|
||||
|
||||
resolveId(id) {
|
||||
if (id === 'virtual:my-module') return id;
|
||||
},
|
||||
|
||||
load(id) {
|
||||
if (id === 'virtual:my-module') {
|
||||
return 'export default 42';
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Vite virtual module
|
||||
```ts
|
||||
// Plugin 가 virtual module
|
||||
load(id) {
|
||||
if (id === 'virtual:routes') {
|
||||
const routes = scanFiles('src/routes');
|
||||
return `export default ${JSON.stringify(routes)}`;
|
||||
}
|
||||
}
|
||||
|
||||
// User code
|
||||
import routes from 'virtual:routes';
|
||||
```
|
||||
|
||||
→ Build-time code generation.
|
||||
|
||||
### Bundle 크기 분석
|
||||
```bash
|
||||
# esbuild
|
||||
esbuild --analyze=verbose
|
||||
|
||||
# Vite + rollup-plugin-visualizer
|
||||
import { visualizer } from 'rollup-plugin-visualizer';
|
||||
plugins: [visualizer()]
|
||||
```
|
||||
|
||||
### CSS tree-shake
|
||||
```css
|
||||
/* Used */
|
||||
.btn { ... }
|
||||
|
||||
/* Unused */
|
||||
.unused { ... }
|
||||
```
|
||||
|
||||
```js
|
||||
// PurgeCSS 또는 Lightning CSS 의 unused class detection
|
||||
```
|
||||
|
||||
→ Tailwind 가 자체.
|
||||
|
||||
### CSS sourcemap
|
||||
```ts
|
||||
{
|
||||
sourceMap: true,
|
||||
}
|
||||
```
|
||||
|
||||
→ Browser DevTools 에서 original source.
|
||||
|
||||
### Speed comparison
|
||||
```
|
||||
Webpack: baseline.
|
||||
Vite (dev): 0.1x time.
|
||||
Vite (build): 0.3x.
|
||||
esbuild: 0.05x.
|
||||
Bun build: 0.04x.
|
||||
```
|
||||
|
||||
### Bun 의 약점
|
||||
```
|
||||
- npm ecosystem 이 일부 안 작동.
|
||||
- Production 안정성 (2026 stable 가 새).
|
||||
- Tooling integration 부족.
|
||||
- Native module 일부 X.
|
||||
|
||||
→ Side project / new = OK.
|
||||
큰 enterprise = Node 가 안전.
|
||||
```
|
||||
|
||||
### Lightning CSS 의 약점
|
||||
```
|
||||
- PostCSS plugin 호환 X.
|
||||
- 일부 modern CSS 기능 not yet.
|
||||
|
||||
→ Tailwind 4+ 가 가장 큰 user.
|
||||
```
|
||||
|
||||
### React + Bun
|
||||
```bash
|
||||
bun create vite my-app -- --template react-ts
|
||||
cd my-app
|
||||
bun install
|
||||
bun run dev
|
||||
```
|
||||
|
||||
→ Vite 가 그대로. Runtime 가 Bun.
|
||||
|
||||
### Next.js + Bun
|
||||
```bash
|
||||
bun create next-app my-app
|
||||
cd my-app
|
||||
bun run dev
|
||||
```
|
||||
|
||||
→ Next 가 Webpack/Turbopack 사용. Bun 가 npm replacement.
|
||||
|
||||
### Production deploy (Bun)
|
||||
```dockerfile
|
||||
FROM oven/bun:1
|
||||
WORKDIR /app
|
||||
COPY package.json bun.lockb ./
|
||||
RUN bun install --production
|
||||
COPY . .
|
||||
CMD ["bun", "src/server.ts"]
|
||||
```
|
||||
|
||||
→ Hono + Bun = 가장 빠른 stack.
|
||||
|
||||
### Esbuild loader
|
||||
```ts
|
||||
{
|
||||
loader: {
|
||||
'.svg': 'text', // SVG 가 string
|
||||
'.png': 'dataurl', // base64
|
||||
'.txt': 'text',
|
||||
'.wasm': 'binary',
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Bun 의 .env
|
||||
```ts
|
||||
// 자동 load
|
||||
import.meta.env.MY_VAR
|
||||
|
||||
// .env, .env.local, .env.{NODE_ENV}
|
||||
```
|
||||
|
||||
→ Vite 와 비슷.
|
||||
|
||||
### Workspace (monorepo)
|
||||
```json
|
||||
// package.json
|
||||
{
|
||||
"workspaces": ["packages/*", "apps/*"]
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
bun install
|
||||
# → 모든 workspace install.
|
||||
```
|
||||
|
||||
### Future
|
||||
```
|
||||
- Bun 가 Node 대안 (실험적 → production)
|
||||
- Lightning CSS = Tailwind 의 future
|
||||
- esbuild / swc = compiler standard
|
||||
- Webpack 의 share 줄어듦.
|
||||
```
|
||||
|
||||
## 🤔 의사결정 기준
|
||||
| 작업 | 추천 |
|
||||
|---|---|
|
||||
| Modern Bun stack | Bun + Hono |
|
||||
| React app | Vite + esbuild |
|
||||
| 큰 enterprise | Node + Vite |
|
||||
| 빠른 CLI | Bun shell |
|
||||
| CSS-heavy | Lightning CSS |
|
||||
| Tailwind 4 | Lightning CSS (자동) |
|
||||
| Custom build | esbuild plugin |
|
||||
| Monorepo | Bun workspace |
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **모든 거 Bun (production)**: 일부 깨짐.
|
||||
- **PostCSS + Lightning CSS 둘 다**: 충돌.
|
||||
- **CSS tree-shake 없음**: 큰 bundle.
|
||||
- **Sourcemap prod**: leak.
|
||||
- **Big bun.lockb in git**: OK (sync 위해).
|
||||
- **ESM + CJS 혼동**: import 깨짐.
|
||||
|
||||
## 🤖 LLM 활용 힌트
|
||||
- Bun = JS runtime + bundler + test + npm 한 binary.
|
||||
- Lightning CSS = Tailwind 4 + Rust.
|
||||
- esbuild plugin 가 pluggable.
|
||||
- Modern stack = native (Rust / Go) tool.
|
||||
|
||||
## 🔗 관련 문서
|
||||
- [[Frontend_Turbopack_Rspack]]
|
||||
- [[Runtime_Bun_Deno_Comparison]]
|
||||
- [[TS_Build_Bundler_Patterns]]
|
||||
Reference in New Issue
Block a user