9148c358d0
Topic_Agent/Topic_Blog/Topics/Topics_Biz/Topics_Meeting/Topics_Rag의 마크다운 지식 문서를 Topic_General/Topic_Programming/Topic_Graphic/Topic_Business 4개 카테고리로 재분류. - 중복 제거: frontmatter의 status:duplicate/merged + duplicate_of/redirect_to 필드로 자기 자신을 중복으로 선언한 리다이렉트 stub 1032개 제거, 완전 동일 내용 파일 472개 제거, 동일 파일명·다른 내용 충돌 시 더 큰(완전한) 버전만 유지(162개 제거) — 총 1639개 중복 제거. - 분류: 폴더 단위로 명확한 항목(AI_and_ML/Coding/Architecture 등 → Programming, Comfyui/Visual_Effects → Graphic, Topics_Biz/Topics_Meeting/사업 등 → Business, Poetic_Blog_Writing/창의성/Game_Design 등 → General)은 폴더 우선순위로, 나머지 혼재 폴더(Topic_Agent/Topic_Blog/Topics 루트/Thinking & Reasoning/Other/UI_UX_Assets)는 title/tags 키워드 스코어링으로 파일 단위 분류(불명확한 경우 General로 폴백). 원본 폴더명은 "From_*" 서브폴더로 보존해 추적 가능성 유지. - 최종 배치: Programming 2784 / General 1608 / Graphic 285 / Business 249 = 4926개 문서. - 에이전트 운영 상태(.astra/.agent/.obsidian/sessions/memory/_company/docs/lessons/_shared/src)는 지식 콘텐츠가 아니므로 재분류 대상에서 제외하고 원위치 유지. - Topics/Topic_email(상위 보호 폴더 Topic_email과 파일명 100% 중복) 삭제 — 보호 폴더 자체는 미변경. - 완전히 비게 된 Topic_Agent/Topic_Blog/Topics_Biz/Topics_Rag 폴더 제거.
6.6 KiB
6.6 KiB
id, title, category, status, source_trust_level, verification_status, created_at, updated_at, tags, tech_stack, applied_in, aliases
| id | title | category | status | source_trust_level | verification_status | created_at | updated_at | tags | tech_stack | applied_in | aliases | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| frontend-css-migration-tailwind | CSS Migration — CSS-in-JS → Tailwind / native | Coding | draft | B | conceptual | 2026-05-09 | 2026-05-09 |
|
|
|
CSS Migration
CSS-in-JS (Emotion, styled-components) 가 cost 큰. Tailwind 4 / native CSS / Panda CSS 가 modern.
📖 핵심 개념
- CSS-in-JS = runtime cost (parse, hydrate).
- Tailwind = build-time, 0 runtime.
- Panda CSS / Vanilla Extract = atomic CSS-in-JS.
- Native CSS = modern feature 가 충분.
💻 코드 패턴
옛 (Emotion / styled-components)
import styled from '@emotion/styled';
const Button = styled.button<{ primary?: boolean }>`
padding: 8px 16px;
background: ${({ primary }) => primary ? 'blue' : 'gray'};
color: white;
border-radius: 4px;
`;
<Button primary>Click</Button>
→ Runtime parsing. Hydration cost. SSR slow.
Tailwind
<button className='px-4 py-2 bg-blue-500 text-white rounded'>
Click
</button>
// 또는 cva
import { cva } from 'class-variance-authority';
const button = cva('px-4 py-2 rounded', {
variants: {
color: { blue: 'bg-blue-500 text-white', gray: 'bg-gray-500 text-white' },
},
});
<button className={button({ color: 'blue' })}>Click</button>
→ 0 runtime. Build-time only.
Tailwind 4 (Lightning CSS)
@import "tailwindcss";
@theme {
--color-primary: oklch(0.7 0.15 270);
}
→ JS config 없음. CSS-native.
Panda CSS (atomic CSS-in-JS)
import { css } from '../styled-system/css';
<button className={css({ px: 4, py: 2, bg: 'blue.500', color: 'white' })}>
Click
</button>
→ Build-time atomic CSS. Type-safe. Tailwind 식 + JS DX.
Vanilla Extract (zero-runtime)
// button.css.ts
import { style } from '@vanilla-extract/css';
export const button = style({
padding: '8px 16px',
background: 'blue',
color: 'white',
});
import { button } from './button.css';
<button className={button}>Click</button>
→ TypeScript + zero runtime.
CSS Modules (legacy 가 OK)
// Button.module.css
.button { padding: 8px 16px; background: blue; }
// Button.tsx
import styles from './Button.module.css';
<button className={styles.button}>Click</button>
→ Scope 자동. Modern alternative 가 native @scope.
Migration: styled-components → Tailwind
Step 1: Add Tailwind.
Step 2: 매 component 의 css = Tailwind class.
Step 3: Remove styled-components.
→ 점진. 1 component 씩.
Migration script
# Twin macro 등 의 도구
npx codemod styled-components-to-tailwind
→ Manual review 가 필요.
Why migrate?
CSS-in-JS cost:
- Bundle size (Emotion: 12 KB).
- Runtime parse.
- Hydration delay.
- SSR overhead.
- Devtools 가 cryptic class.
Tailwind:
- 0 runtime.
- 1 css file.
- Browser cache.
- Devtools 친화 (class).
→ Production performance ↑.
Cons of Tailwind
- Class string 가 길음 (long).
- Learn curve.
- Custom design system = config.
- Dynamic style 어려움 (config 만).
→ shadcn/ui + cva 가 답.
Dynamic style (Tailwind)
// ❌ 동적 class
<div className={`bg-${color}-500`}>...</div>
// → JIT 가 build 시 detect 못 함.
// ✅ 명시
const colorClass = {
red: 'bg-red-500',
blue: 'bg-blue-500',
}[color];
<div className={colorClass}>...</div>
Tailwind v4 의 변화
- CSS-native (no JS config).
- Lightning CSS (Rust).
- @theme directive.
- 100x 빠른 build.
- 작은 css output.
Native CSS의 modern features
/* Container query */
.card {
container-type: inline-size;
}
@container (min-width: 400px) { ... }
/* :has() */
.form:has(:invalid) { ... }
/* @scope */
@scope (.card) {
h2 { color: blue; }
}
/* CSS variables */
:root { --primary: oklch(0.7 0.15 270); }
→ Tailwind 없이도 CSS 가 powerful.
Theme (Tailwind)
@theme {
--color-primary: oklch(0.7 0.15 270);
--font-sans: 'Inter', sans-serif;
--shadow-card: 0 4px 12px rgba(0,0,0,0.1);
}
<div className='bg-primary font-sans shadow-card'>...</div>
Dark mode
@media (prefers-color-scheme: dark) {
:root {
--color-bg: black;
}
}
/* Or class-based */
.dark {
--color-bg: black;
}
<html className='dark'>
CSS-in-JS 가 적절 한 경우
- 매우 동적 (theme switch runtime).
- Library 가 CSS-in-JS 사용.
- Team 가 익숙.
→ 하지만 modern = native CSS 가 충분.
Astro CSS
---
---
<div class='card'>...</div>
<style>
.card {
/* Scoped automatically */
padding: 16px;
}
</style>
→ Component-scoped CSS native.
Production
- Vercel docs: Tailwind.
- GitHub: 옛 Sass → 새 design system.
- Notion: 자체 CSS.
- Stripe: Sass + design system.
- shadcn/ui: Tailwind.
Real-world migration
1. Audit current CSS.
2. Pick 1 (Tailwind / Panda / native).
3. Component 별 migrate.
4. Test (visual regression).
5. Remove old.
→ 매 milestone 의 measurable.
Bundle size
Emotion: 12 KB runtime.
Styled-components: 16 KB.
Tailwind: 0 (build).
Panda: 0 (build).
Vanilla Extract: 0.
→ Modern = 0 runtime.
LLM 도움
- Style migration 의 component 별.
- Tailwind class 의 codegen.
- Visual regression 검증.
→ Cursor 의 큰 use case.
Tools
- Tailwind CSS (v4).
- Panda CSS.
- Vanilla Extract.
- StyleX (Meta).
- Lightning CSS.
- PostCSS (legacy).
StyleX (Meta)
import * as stylex from '@stylex/stylex';
const styles = stylex.create({
base: { padding: 16, background: 'blue' },
});
<button {...stylex.props(styles.base)}>Click</button>
→ Atomic + zero runtime + type-safe.
🤔 의사결정 기준
| 상황 | 추천 |
|---|---|
| New project | Tailwind 4 |
| Type-safe + JS | Panda CSS / Vanilla Extract |
| 매우 dynamic | StyleX / Emotion |
| 작은 / static | Native CSS |
| Component library | shadcn (Tailwind) |
| Migration | 점진 + visual test |
❌ 안티패턴
- CSS-in-JS in 새 project: runtime cost.
- Dynamic Tailwind class: JIT miss.
- Tailwind + Sass: 둘 다 사용.
- Migration big bang: visual regression.
- No design tokens: drift.
🤖 LLM 활용 힌트
- Tailwind 4 = modern default.
- Panda / Vanilla Extract = type-safe alternative.
- Native CSS 가 충분 (modern feature).
- CSS-in-JS = legacy migration.