Communitygithub.com

vite-patterns

Vite 빌드 도구 패턴 (설정, 플러그인, HMR, 환경 변수, 프록시 설정, SSR, 라이브러리 모드, 의존성 사전 번들링, 빌드 최적화 포함). vite.config.ts, Vite 플러그인 또는 Vite 기반 프로젝트 작업 시 활성화됩니다.

vite-patterns란 무엇인가요?

이 스킬은 Vite 8+ 프로젝트를 위한 빌드 도구 및 개발 서버 패턴을 제공합니다. 설정, 플러그인, HMR, 환경 변수, 프록시, 라이브러리 모드, 의존성 사전 번들링 및 일반적인 프로덕션 문제를 다루며, 개발자와 AI 에이전트가 Vite 기반 프로젝트를 효율적으로 구성하고 최적화할 수 있도록 돕습니다. 주요 기능으로는 `vite.config.ts` 설정 구조, 필수 및 커스텀 플러그인 작성법, `import.meta.hot`을 통한 수동 HMR, `VITE_` 접두사 환경 변수의 클라이언트 노출 및 보안 주의사항, 서버 프록시 설정, 수동 청크 분할 및 배럴 파일 회피와 같은 빌드 최적화, 라이브러리 모드에서 타입 생성과 피어 의존성 외부화, SSR 외부화 및 의존성 사전 번들링 구성이 포함됩니다. 또한 개발과 빌드 환경의 불일치, 배포 후 캐시 문제, Docker/컨테이너 설정, 모노레포 파일 접근 등 일반적인 함정을 해결하는 방법과 `envPrefix`를 빈 문자열로 설정하는 것과 같은 안티 패턴을 경고합니다. 이 스킬은 Claude Code, Cursor, Codex와 같은 AI 코딩 에이전트에서 Vite 관련 작업 시 사용하기 적합합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/ECC/tree/main/skills/vite-patterns

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Vite 패턴

Vite 8+ 프로젝트를 위한 빌드 도구 및 개발 서버 패턴입니다. 설정, 환경 변수, 프록시 설정, 라이브러리 모드, 의존성 사전 번들링 및 일반적인 프로덕션 문제를 다룹니다.

사용 시점

  • vite.config.ts 또는 vite.config.js 설정
  • 환경 변수 또는 .env 파일 설정
  • API 백엔드를 위한 개발 서버 프록시 구성
  • 빌드 출력 최적화 (청크, 축소, 에셋)
  • build.lib로 라이브러리 게시
  • 의존성 사전 번들링 또는 CJS/ESM 상호 운용성 문제 해결
  • HMR, 개발 서버 또는 빌드 오류 디버깅
  • Vite 플러그인 선택 또는 순서 지정

작동 방식

  • 개발 모드는 소스 파일을 네이티브 ESM으로 제공합니다 — 번들링하지 않습니다. 모듈 요청 시 변환이 온디맨드로 발생하므로 콜드 스타트가 빠르고 HMR이 정확합니다.
  • 빌드 모드는 Rolldown(v7+) 또는 Rollup(v5–v6)을 사용하여 트리 셰이킹, 코드 분할 및 Oxc 기반 축소를 통해 프로덕션용 애플리케이션을 번들링합니다.
  • 의존성 사전 번들링은 CJS/UMD 의존성을 esbuild를 통해 한 번 ESM으로 변환하고 결과를 node_modules/.vite에 캐시하여 이후 시작 시 작업을 건너뜁니다.
  • 플러그인은 개발 및 빌드에서 통합 인터페이스를 공유합니다. 동일한 플러그인 객체가 개발 서버의 온디맨드 변환과 프로덕션 파이프라인 모두에서 작동합니다.
  • 환경 변수는 빌드 타임에 정적으로 인라인됩니다. VITE_ 접두사가 있는 변수는 번들에서 공개 상수가 되고, 접두사가 없는 것은 클라이언트 코드에 보이지 않습니다.

예제

설정 구조

기본 설정

// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: { '@': new URL('./src', import.meta.url).pathname },
  },
})

조건부 설정

// vite.config.ts
import { defineConfig, loadEnv } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig(({ command, mode }) => {
  const env = loadEnv(mode, process.cwd())   // VITE_ 접두사만 (안전)

  return {
    plugins: [react()],
    server: command === 'serve' ? { port: 3000 } : undefined,
    define: {
      __API_URL__: JSON.stringify(env.VITE_API_URL),
    },
  }
})

주요 설정 옵션

키기본값설명
root'.'프로젝트 루트 (index.html이 있는 위치)
base'/'배포된 에셋의 공개 기본 경로
envPrefix'VITE_'클라이언트에 노출되는 환경 변수의 접두사
build.outDir'dist'출력 디렉터리
build.minify'oxc'축소기 ('oxc', 'terser' 또는 false)
build.sourcemapfalsetrue, 'inline' 또는 'hidden'

플러그인

필수 플러그인

대부분의 플러그인 요구 사항은 잘 유지 관리되는 몇 가지 패키지로 충족됩니다. 직접 작성하기 전에 먼저 이것들을 사용하세요.

플러그인목적사용 시점
@vitejs/plugin-react-swcSWC를 통한 React HMR + Fast RefreshReact 앱의 기본 (Babel 변형보다 빠름)
@vitejs/plugin-reactBabel을 통한 React HMR + Fast RefreshBabel 플러그인이 필요한 경우에만 (emotion, MobX 데코레이터)
@vitejs/plugin-vueVue 3 SFC 지원Vue 앱
vite-plugin-checkerHMR 오버레이와 함께 워커 스레드에서 tsc + ESLint 실행모든 TypeScript 앱 — Vite는 vite build 중 타입 검사를 하지 않습니다
vite-tsconfig-pathstsconfig.json paths 별칭 준수tsconfig.json에 이미 별칭이 있는 경우
vite-plugin-dts라이브러리 모드에서 .d.ts 파일 생성TypeScript 라이브러리 게시
vite-plugin-svgrSVG를 React 컴포넌트로 가져오기SVG를 컴포넌트로 사용하는 React 앱
rollup-plugin-visualizer번들 트리맵/선버스트 보고서주기적인 번들 크기 감사 (enforce: 'post' 사용)
vite-plugin-pwa설정 없는 PWA + Workbox오프라인 지원 앱

중요 경고: vite build는 트랜스파일하지만 타입 검사는 하지 않습니다. vite-plugin-checker를 추가하거나 CI에서 tsc --noEmit을 실행하지 않으면 타입 오류가 자동으로 프로덕션에 배포됩니다.

커스텀 플러그인 작성

작성은 드뭅니다 — 대부분의 요구 사항은 기존 플러그인으로 충족됩니다. 필요할 때는 vite.config.ts에서 인라인으로 시작하고 재사용되는 경우에만 분리하세요.

// vite.config.ts — 최소 인라인 플러그인
function myPlugin(): Plugin {
  return {
    name: 'my-plugin',                       // 필수, 고유해야 함
    enforce: 'pre',                           // 'pre' | 'post' (선택 사항)
    apply: 'build',                           // 'build' | 'serve' (선택 사항)
    transform(code, id) {
      if (!id.endsWith('.custom')) return
      return { code: transformCustom(code), map: null }
    },
  }
}

주요 훅: transform (소스 수정), resolveId + load (가상 모듈), transformIndexHtml (HTML에 주입), configureServer (개발 미들웨어 추가), hotUpdate (커스텀 HMR — v7+에서 폐지된 handleHotUpdate 대체).

가상 모듈은 \0 접두사 규칙을 사용합니다 — resolveId가 '\0virtual:my-id'를 반환하여 다른 플러그인이 건너뛰도록 합니다. 사용자 코드는 'virtual:my-id'를 가져옵니다.

전체 플러그인 API는 vite.dev/guide/api-plugin을 참조하세요. 개발 중에는 vite-plugin-inspect를 사용하여 변환 파이프라인을 디버깅하세요.

HMR API

프레임워크 플러그인(@vitejs/plugin-react, @vitejs/plugin-vue 등)은 HMR을 자동으로 처리합니다. 커스텀 상태 저장소, 개발 도구 또는 업데이트 간에 상태를 유지해야 하는 프레임워크에 구애받지 않는 유틸리티를 구축할 때만 import.meta.hot을 직접 사용하세요.

// src/store.ts — 바닐라 모듈의 수동 HMR
if (import.meta.hot) {
  // 업데이트 간 상태 유지 (반드시 MUTATE해야 하며, .data를 재할당하지 마세요)
  import.meta.hot.data.count = import.meta.hot.data.count ?? 0

  // 모듈이 교체되기 전에 부작용 정리
  import.meta.hot.dispose((data) => clearInterval(data.intervalId))

  // 이 모듈의 자체 업데이트 수락
  import.meta.hot.accept()
}

모든 import.meta.hot 코드는 프로덕션 빌드에서 트리 셰이킹됩니다 — 가드 제거가 필요 없습니다.

환경 변수

Vite는 .env, .env.local, .[mode], .env.[mode].local 파일을 순서대로 로드합니다 (나중에 로드된 것이 이전 것을 덮어씁니다). *.local 파일은 git에서 무시되며 로컬 비밀용입니다.

클라이언트 측 접근

VITE_ 접두사가 있는 변수만 클라이언트 코드에 노출됩니다:

import.meta.env.VITE_API_URL   // 문자열
import.meta.env.MODE            // 'development' | 'production' | 사용자 정의
import.meta.env.BASE_URL        // 기본 설정 값
import.meta.env.DEV             // 불리언
import.meta.env.PROD            // 불리언
import.meta.env.SSR             // 불리언

설정에서 환경 변수 사용

// vite.config.ts
import { defineConfig, loadEnv } from 'vite'

export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd())          // VITE_ 접두사만 (안전)
  return {
    define: {
      __API_URL__: JSON.stringify(env.VITE_API_URL),
    },
  }
})

보안

VITE_ 접두사는 보안 경계가 아닙니다

VITE_ 접두사가 있는 모든 변수는 빌드 타임에 클라이언트 번들에 정적으로 인라인됩니다. 축소, base64 인코딩 및 소스 맵 비활성화는 이를 숨기지 않습니다. 결정적인 공격자는 제공된 JavaScript에서 VITE_ 변수를 추출할 수 있습니다.

규칙: 공개 값(API URL, 기능 플래그, 공개 키)만 VITE_ 변수에 넣으세요. 비밀(API 토큰, 데이터베이스 URL, 개인 키)은 반드시 API 또는 서버리스 함수 뒤에 서버 측에 있어야 합니다.

loadEnv('') 함정

// 나쁨: 세 번째 인수로 ''를 전달하면 모든 환경 변수(서버 비밀 포함)를 로드하여
// `define`을 통해 클라이언트 코드에 인라인할 수 있게 됩니다.
const env = loadEnv(mode, process.cwd(), '')

// 좋음: 명시적 접두사 목록
const env = loadEnv(mode, process.cwd(), ['VITE_', 'APP_'])

프로덕션의 소스 맵

프로덕션 소스 맵은 원본 소스 코드를 유출합니다. 오류 추적기(Sentry, Bugsnag)에 업로드하지 않는 한 비활성화하고 그 후 로컬에서 삭제하세요:

build: {
  sourcemap: false,                                  // 기본값 — 이렇게 유지하세요
}

.gitignore 체크리스트

  • .env.local, .env.*.local — 로컬 비밀 재정의
  • dist/ — 빌드 출력
  • node_modules/.vite — 사전 번들 캐시 (오래된 항목으로 인해 유령 오류 발생)

서버 프록시

// vite.config.ts — server.proxy
server: {
  proxy: {
    '/foo': 'http://localhost:4567',                    // 문자열 약어

    '/api': {
      target: 'http://localhost:8080',
      changeOrigin: true,                               // 가상 호스트 백엔드에 필요
      rewrite: (path) => path.replace(/^\/api/, ''),
    },
  },
}

WebSocket 프록시의 경우 경로 구성에 ws: true를 추가하세요.

빌드 최적화

수동 청크

// vite.config.ts — build.rolldownOptions
build: {
  rolldownOptions: {
    output: {
      // 객체 형태: 특정 패키지 그룹화
      manualChunks: {
        'react-vendor': ['react', 'react-dom'],
        'ui-vendor': ['@radix-ui/react-dialog', '@radix-ui/react-popover'],
      },
    },
  },
}
// 함수 형태: 휴리스틱으로 분할
manualChunks(id) {
  if (id.includes('node_modules/react')) return 'react-vendor'
  if (id.includes('node_modules')) return 'vendor'
}

성능

배럴 파일 회피

배럴 파일(디렉토리의 모든 것을 다시 내보내는 index.ts)은 단일 심볼을 가져올 때도 Vite가 다시 내보낸 모든 파일을 로드하도록 강제합니다. 공식 문서에서 지목하는 1위 개발 서버 속도 저하 원인입니다.

// 나쁨 — 하나의 유틸을 가져오면 Vite가 전체 배럴을 로드함
import { slash } from '@/utils'

// 좋음 — 직접 가져오기, 해당 파일만 로드됨
import { slash } from '@/utils/slash'

가져오기 확장자를 명시적으로 지정

각 암시적 확장자는 resolve.extensions를 통해 최대 6번의 파일 시스템 검사를 강제합니다. 대규모 코드베이스에서는 이 비용이 누적됩니다.

// 나쁨
import Component from './Component'

// 좋음
import Component from './Component.tsx'

tsconfig.json의 allowImportingTsExtensions와 resolve.extensions를 실제 사용하는 확장자로만 좁히세요.

핫 경로 웜업

server.warmup.clientFiles는 브라우저가 요청하기 전에 알려진 핫 진입점을 사전 변환하여 대규모 앱의 콜드 로드 요청 폭포를 제거합니다.

// vite.config.ts
server: {
  warmup: {
    clientFiles: ['./src/main.tsx', './src/routes/**/*.tsx'],
  },
}

느린 개발 서버 프로파일링

vite dev가 느리다고 느껴지면 vite --profile로 시작하고, 앱과 상호 작용한 다음 p+enter를 눌러 .cpuprofile을 저장하세요. Speedscope에서 로드하여 어떤 플러그인이 시간을 소비하는지 찾으세요 — 일반적으로 커뮤니티 플러그인의 buildStart, config 또는 configResolved 훅입니다.

라이브러리 모드

npm 패키지를 게시할 때는 build.lib를 사용하세요. 설정 세부 사항보다 두 가지 함정이 더 중요합니다:

  1. 타입이 생성되지 않습니다 — vite-plugin-dts를 추가하거나 tsc --emitDeclarationOnly를 별도로 실행하세요.
  2. 피어 의존성은 반드시 외부화되어야 합니다 — 목록에 없는 피어가 라이브러리에 번들링되어 사용자에게 중복 런타임 오류를 발생시킵니다.
// vite.config.ts
build: {
  lib: {
    entry: 'src/index.ts',
    formats: ['es', 'cjs'],
    fileName: (format) => `my-lib.${format}.js`,
  },
  rolldownOptions: {
    external: ['react', 'react-dom', 'react/jsx-runtime'],  // 모든 피어 의존성
  },
}

SSR 외부화

단순 createServer({ middlewareMode: true }) 설정은 프레임워크 작성자의 영역입니다. 대부분의 앱은 Nuxt, Remix, SvelteKit, Astro 또는 TanStack Start를 대신 사용해야 합니다. 프레임워크 사용자로서 조정할 것은 의존성이 SSR에서 깨질 때 외부화 설정입니다:

// vite.config.ts — ssr 옵션
ssr: {
  external: ['node-native-package'],           // SSR 번들에서 require()로 유지
  noExternal: ['esm-only-package'],            // SSR 출력에 강제 번들링 (대부분의 SSR 오류 수정)
  target: 'node',                              // 'node' 또는 'webworker'
}

의존성 사전 번들링

Vite는 의존성을 사전 번들링하여 CJS/UMD를 ESM으로 변환하고 요청 수를 줄입니다.

// vite.config.ts — optimizeDeps
optimizeDeps: {
  include: [
    'lodash-es',                              // 알려진 무거운 의존성 강제 사전 번들링
    'cjs-package',                            // 상호 운용성 문제를 일으키는 CJS 의존성
    'deep-lib/components/**',                 // 깊은 가져오기를 위한 glob
  ],
  exclude: ['local-esm-package'],             // 제외된 경우 유효한 ESM이어야 함
  force: true,                                // 캐시 무시, 다시 최적화 (임시 디버깅)
}

일반적인 함정

개발과 빌드 불일치

개발은 변환에 esbuild/Rolldown을 사용하고, 빌드는 번들링에 Rolldown을 사용합니다. CJS 라이브러리는 둘 사이에서 다르게 동작할 수 있습니다. 배포하기 전에 항상 vite build && vite preview로 확인하세요.

배포 후 오래된 청크

새 빌드는 새 청크 해시를 생성합니다. 활성 세션이 있는 사용자는 더 이상 존재하지 않는 이전 파일 이름을 요청합니다. Vite에는 기본 제공 솔루션이 없습니다. 완화 방법:

  • 배포 기간 동안 이전 dist/assets/ 파일을 유지
  • 라우터에서 동적 가져오기 오류를 잡아서 페이지 새로고침 강제

Docker 및 컨테이너

Vite는 기본적으로 localhost에 바인딩되며 컨테이너 외부에서 접근할 수 없습니다:

// vite.config.ts — Docker/컨테이너 설정
server: {
  host: true,                                  // 0.0.0.0에 바인딩
  hmr: { clientPort: 3000 },                   // 리버스 프록시 뒤에 있는 경우
}

모노레포 파일 접근

Vite는 파일 제공을 프로젝트 루트로 제한합니다. 루트 외부의 패키지는 차단됩니다:

// vite.config.ts — 모노레포 파일 접근
server: {
  fs: {
    allow: ['..'],                             // 상위 디렉터리 허용 (워크스페이스 루트)
  },
}

안티 패턴

// 나쁨: envPrefix를 ''로 설정하면 모든 환경 변수(비밀 포함)가 클라이언트에 노출됨
envPrefix: ''

// 나쁨: Vite 번들에서 require()가 작동한다고 가정

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/content-engine

Create platform-native content systems for X, LinkedIn, TikTok, YouTube, newsletters, and repurposed multi-platform campaigns. Use when the user wants social posts, threads, scripts, content calendars, or one source asset adapted cleanly across platforms.

affaan-m/ECC

Multi-platform content distribution across X, LinkedIn, Threads, and Bluesky. Adapts content per platform using content-engine patterns. Never posts identical content cross-platform. Use when the user wants to distribute content across social platforms.

affaan-m/fal-ai-media

Unified media generation via fal.ai MCP — image, video, and audio. Covers text-to-image (Nano Banana), text/image-to-video (Seedance, Kling, Veo 3), text-to-speech (CSM-1B), and video-to-audio (ThinkSound). Use when the user wants to generate images, videos, or audio with AI.

affaan-m/manim-video

日本語翻訳:このファイルは manim-video 用の日本語翻訳が必要です

affaan-m/remotion-video-creation

Remotion のベストプラクティス - React で動画を作成する。3D、アニメーション、音声、字幕、チャート、トランジションなどをカバーするドメイン固有の29のルール。

affaan-m/video-editing

AI-assisted video editing workflows for cutting, structuring, and augmenting real footage. Covers the full pipeline from raw capture through FFmpeg, Remotion, ElevenLabs, fal.ai, and final polish in Descript or CapCut. Use when the user wants to edit video, cut footage, create vlogs, or build video content.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

agent-self-evaluation

Use after completing any non-trivial task. The agent self-rates its output on 5 axes — accuracy, completeness, clarity, actionability, conciseness — with concrete evidence per criterion. Produces a structured 1-5 scorecard with specific improvement suggestions.

agent-sort

Build an evidence-backed ECC install plan for a specific repo by sorting skills, commands, rules, hooks, and extras into DAILY vs LIBRARY buckets using parallel repo-aware review passes. Use when ECC should be trimmed to what a project actually needs instead of loading the full bundle.

ai-first-engineering

Engineering operating model for teams where AI agents generate a large share of implementation output. Use when setting team process, review gates, or ownership rules for a codebase largely written by agents.

ai-regression-testing

Regression testing strategies for AI-assisted development. Sandbox-mode API testing without database dependencies, automated bug-check workflows, and patterns to catch AI blind spots where the same model writes and reviews code. Use when adding regression coverage to AI-assisted code, or when the same model both wrote and reviewed a change.

android-clean-architecture

Clean Architecture patterns for Android and Kotlin Multiplatform projects — module structure, dependency rules, UseCases, Repositories, and data layer patterns. Use when structuring modules, layers, or data flow in an Android or KMP project.

angular-developer

Generates Angular code and provides architectural guidance. Trigger when creating projects, components, or services, or for best practices on reactivity (signals, linkedSignal, resource), forms, dependency injection, routing, SSR, accessibility (ARIA), animations, styling (component styles, Tailwind CSS), testing, or CLI tooling.

관련 스킬