🔌 통합 가이드
AdorableCSS와 다른 도구들의 조화로운 공존
🎯 Overview
AdorableCSS는 독립적으로도 훌륭하지만, 기존 도구들과 함께 사용할 때 더욱 강력해집니다.
🛠 빌드 도구 통합
Webpack
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
// AdorableCSS PostCSS 플러그인 (개발 중)
require('adorable-css/postcss')
]
}
}
}
]
}
]
}
}
Vite
// vite.config.js
import { defineConfig } from 'vite'
import { adorableCSS } from 'adorable-css/vite'
export default defineConfig({
plugins: [
adorableCSS({
// 옵션
purge: process.env.NODE_ENV === 'production',
themes: ['light', 'dark']
})
],
css: {
modules: {
// CSS Modules와 함께 사용
localsConvention: 'camelCase'
}
}
})
Parcel
// package.json
{
"adorable-css": {
"purge": true,
"themes": ["light", "dark"]
}
}
// .parcelrc
{
"extends": "@parcel/config-default",
"transformers": {
"*.css": ["@parcel/transformer-css", "adorable-css/parcel"]
}
}
🎨 CSS 프레임워크 공존
TailwindCSS와 함께
// tailwind.config.js
module.exports = {
prefix: 'tw-', // Tailwind 클래스에 prefix 추가
content: ['./src/**/*.{js,jsx,ts,tsx}'],
theme: {
extend: {
// AdorableCSS 토큰 재사용
colors: {
primary: 'var(--adorable-primary)',
secondary: 'var(--adorable-secondary)'
}
}
}
}
<!-- 혼용 예시 -->
<div class="
card <!-- AdorableCSS -->
tw-backdrop-blur-lg <!-- TailwindCSS -->
hbox(pack) <!-- AdorableCSS -->
">
<h1 class="heading(xl) tw-tracking-tight">
두 프레임워크의 장점 활용
</h1>
</div>
Bootstrap과 함께
// custom-bootstrap.scss
// Bootstrap 변수를 AdorableCSS 토큰으로 오버라이드
$primary: var(--adorable-blue-500);
$secondary: var(--adorable-gray-500);
$border-radius: var(--adorable-radius-md);
@import 'bootstrap/scss/bootstrap';
<!-- 클래스 네임스페이스 분리 -->
<div class="container"> <!-- Bootstrap -->
<div class="hbox(pack) gap(lg)"> <!-- AdorableCSS -->
<button class="btn btn-primary">Bootstrap 버튼</button>
<button class="btn bg(blue-500) c(white)">AdorableCSS 버튼</button>
</div>
</div>
🔧 PostCSS 생태계
PostCSS 플러그인 체인
// postcss.config.js
module.exports = {
plugins: [
// 1. Import 처리
require('postcss-import'),
// 2. AdorableCSS 처리
require('adorable-css/postcss'),
// 3. 중첩 해제
require('postcss-nested'),
// 4. 자동 프리픽서
require('autoprefixer'),
// 5. 최적화 (프로덕션)
process.env.NODE_ENV === 'production' && require('cssnano')
].filter(Boolean)
}
커스텀 PostCSS 플러그인
// postcss-adorable-custom.js
module.exports = (opts = {}) => {
return {
postcssPlugin: 'postcss-adorable-custom',
Once(root, { result }) {
// AdorableCSS 클래스를 감지하고 변환
root.walkRules(rule => {
if (rule.selector.includes('hbox(')) {
// 커스텀 로직
}
})
}
}
}
module.exports.postcss = true
🎯 CSS-in-JS 라이브러리
Styled Components
import styled from 'styled-components'
import { cx } from 'adorable-css'
// AdorableCSS 클래스를 styled components에 적용
const Card = styled.div.attrs(props => ({
className: cx('card', props.interactive && 'hover:shadow(xl)')
}))`
/* 추가 스타일 */
${props => props.featured && `
border: 2px solid var(--adorable-blue-500);
`}
`
// 사용
<Card interactive featured>
<h2 class="heading(md)">하이브리드 접근</h2>
</Card>
Emotion
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react'
const cardStyles = css`
/* Emotion 스타일 */
&:hover {
transform: translateY(-2px);
}
`
function Card({ children }) {
return (
<div
css={cardStyles}
className="card p(xl)" // AdorableCSS
>
{children}
</div>
)
}
🖼 디자인 도구 연동
Figma 플러그인 (개발 중)
// Figma → AdorableCSS 자동 변환
{
"Auto Layout": {
"direction": "horizontal",
"gap": 16,
"padding": 24,
"alignItems": "center",
"justifyContent": "space-between"
}
}
// ↓ 자동 생성
<div class="hbox(middle) gap(auto) gap(md) p(lg)">
Storybook
// .storybook/preview.js
import 'adorable-css'
export const parameters = {
// AdorableCSS 토큰을 Storybook 컨트롤로
controls: {
matchers: {
color: /(background|color)$/i,
spacing: /(padding|margin|gap)$/i,
},
},
}
// 데코레이터로 테마 전환
export const decorators = [
(Story, context) => (
<div data-theme={context.globals.theme}>
<Story />
</div>
),
]
📊 개발자 도구
Chrome DevTools 확장 (계획 중)
// AdorableCSS 클래스 미리보기
// 호버 시 생성되는 CSS 표시
// 토큰 값 실시간 확인
VS Code 통합
// .vscode/adorable.code-snippets
{
"AdorableCSS Button": {
"prefix": "acss-button",
"body": [
"<button class=\"btn ${1|primary,secondary,danger|} ${2|sm,md,lg|}\">",
" ${3:Button Text}",
"</button>"
]
},
"AdorableCSS Card": {
"prefix": "acss-card",
"body": [
"<div class=\"card${1: hover:shadow(xl)}\">",
" $0",
"</div>"
]
}
}
🧪 테스트 도구
Jest 설정
// jest.config.js
module.exports = {
moduleNameMapper: {
// CSS 모듈 모킹
'\\.(css|less|scss|sass)$': 'identity-obj-proxy',
// AdorableCSS 유틸리티
'adorable-css': '<rootDir>/__mocks__/adorable-css.js'
},
setupFilesAfterEnv: ['<rootDir>/jest.setup.js']
}
// jest.setup.js
import '@testing-library/jest-dom'
import 'adorable-css/jest-matchers'
// 커스텀 매처
expect.extend({
toHaveAdorableClass(element, className) {
const hasClass = element.classList.contains(className)
return {
pass: hasClass,
message: () =>
`Expected element ${hasClass ? 'not ' : ''}to have AdorableCSS class "${className}"`
}
}
})
Cypress 통합
// cypress/support/commands.js
Cypress.Commands.add('getByAdorable', (adorableClass) => {
return cy.get(`[class*="${adorableClass}"]`)
})
// 사용
cy.getByAdorable('hbox(pack)').should('be.visible')
cy.getByAdorable('card').first().click()
🚀 CI/CD 파이프라인
GitHub Actions
# .github/workflows/adorable-css.yml
name: AdorableCSS Validation
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: pnpm install
- name: Validate AdorableCSS classes
run: pnpm adorable:validate
- name: Check bundle size
run: pnpm adorable:size
- name: Visual regression test
run: pnpm test:visual
📦 패키지 매니저
PNPM Workspace
# pnpm-workspace.yaml
packages:
- 'packages/*'
- 'apps/*'
# 공유 의존성
shamefully-hoist:
- 'adorable-css'
Monorepo 설정
// turbo.json
{
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**"]
},
"dev": {
"cache": false
},
"adorable:generate": {
"outputs": ["src/generated/**"]
}
}
}
🔍 문제 해결
클래스 충돌
// adorable.config.js
export default {
// 프리픽스 추가
prefix: 'ac-',
// 특정 클래스 제외
blocklist: ['container', 'btn'],
// 안전 모드
safeMode: true
}
스타일 우선순위
/* 레이어 순서 조정 */
@layer reset, libraries, adorable, components, utilities;
@import 'other-library.css' layer(libraries);
@import 'adorable-css' layer(adorable);
📚 추가 리소스
💡 핵심: AdorableCSS는 기존 도구를 대체하는 것이 아니라 보완합니다. 각 도구의 장점을 활용하여 최고의 개발 경험을 만드세요!