ข้ามไปเนื้อหาหลัก

Category: reference

Vite Config Guide — Plugins, Alias, Build Options

vite.config.ts ตั้งแต่ alias, resolve, plugins จนถึง build optimization และ dev server options

· อ่านประมาณ 3 นาที

สารบัญ

โครงสร้างพื้นฐาน

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

export default defineConfig({
  root: '.',           // root directory ของ project
  publicDir: 'public', // ไฟล์ที่ copy ไป dist โดยตรง
  base: '/',           // base URL สำหรับ assets
})

defineConfig ให้ TypeScript types — ไม่จำเป็นต้องใช้ แต่ช่วย autocomplete


Path Alias

import { defineConfig } from 'vite'
import { resolve } from 'path'

export default defineConfig({
  resolve: {
    alias: {
      '@': resolve(__dirname, './src'),
      '@components': resolve(__dirname, './src/components'),
      '@utils': resolve(__dirname, './src/utils'),
      '@assets': resolve(__dirname, './src/assets'),
    },
  },
})
// ใช้ใน code
import { Button } from '@components/Button'
import { formatDate } from '@utils/date'

หมายเหตุ: ถ้าใช้ TypeScript ต้อง sync กับ tsconfig.json ด้วย:

// tsconfig.json
{
  "compilerOptions": {
    "paths": {
      "@/*": ["./src/*"],
      "@components/*": ["./src/components/*"]
    }
  }
}

Dev Server

export default defineConfig({
  server: {
    port: 3000,
    host: true,           // เปิด network access (ใช้กับ Docker หรือ WSL2)
    open: '/dashboard',   // เปิด browser อัตโนมัติที่ path นี้

    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, ''),
      },
      '/ws': {
        target: 'ws://localhost:8080',
        ws: true,         // WebSocket proxy
      },
    },

    cors: true,           // เปิด CORS สำหรับ dev

    hmr: {
      overlay: false,     // ปิด error overlay (ถ้ารบกวน)
    },
  },
})

Build Options

export default defineConfig({
  build: {
    outDir: 'dist',
    assetsDir: 'assets',
    sourcemap: true,              // สร้าง source maps
    minify: 'esbuild',            // 'terser' | 'esbuild' | false
    target: 'es2020',             // target browser/environment
    assetsInlineLimit: 4096,      // inline assets ที่เล็กกว่า 4kB เป็น base64

    rollupOptions: {
      output: {
        // แยก chunks ตามใจ
        manualChunks: {
          vendor: ['react', 'react-dom'],
          utils: ['lodash-es', 'date-fns'],
        },
        // ตั้งชื่อ output files
        entryFileNames: 'assets/[name].[hash].js',
        chunkFileNames: 'assets/[name].[hash].js',
        assetFileNames: 'assets/[name].[hash].[ext]',
      },
      // External dependencies (ไม่ bundle เข้าไป)
      external: ['electron'],
    },

    // ลบ console.log ออกจาก production
    terserOptions: {
      compress: {
        drop_console: true,
        drop_debugger: true,
      },
    },
  },
})

Plugins

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import legacy from '@vitejs/plugin-legacy'
import compression from 'vite-plugin-compression'

export default defineConfig({
  plugins: [
    // React support
    react(),

    // Support older browsers (generates legacy bundle)
    legacy({
      targets: ['defaults', 'not IE 11'],
    }),

    // Gzip/Brotli compression
    compression({
      algorithm: 'brotliCompress',
      ext: '.br',
    }),
  ],
})

Environment Variables

export default defineConfig(({ mode }) => {
  const isProd = mode === 'production'

  return {
    define: {
      // global constants (เข้าถึงผ่าน code โดยตรง)
      __APP_VERSION__: JSON.stringify(process.env.npm_package_version),
      __DEV__: !isProd,
    },
    // ต่าง config ตาม mode
    build: {
      sourcemap: !isProd,
      minify: isProd ? 'esbuild' : false,
    },
  }
})

ตัวแปร Environment ที่ expose ใน client:

.env
.env.local         ← override ส่วนตัว (ไม่ commit)
.env.development   ← เฉพาะ dev
.env.production    ← เฉพาะ production

# ชื่อต้องขึ้นด้วย VITE_ เพื่อ expose
VITE_API_URL=https://api.example.com
VITE_PUBLIC_KEY=pk_live_xxx
// ใช้ใน code
const apiUrl = import.meta.env.VITE_API_URL
const isDev = import.meta.env.DEV

CSS Options

export default defineConfig({
  css: {
    // PostCSS config
    postcss: {
      plugins: [
        autoprefixer(),
        cssnano(),
      ],
    },

    // CSS Modules config
    modules: {
      localsConvention: 'camelCase',  // camelCase ใน JS
      scopeBehaviour: 'local',
    },

    // PreProcessor options
    preprocessorOptions: {
      scss: {
        additionalData: `@use "@/styles/variables" as *;`,
      },
    },
  },
})

Testing กับ Vitest

Vitest config อยู่ใน vite.config.ts เดียวกัน:

/// <reference types="vitest" />
import { defineConfig } from 'vite'

export default defineConfig({
  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: ['./src/test/setup.ts'],
    coverage: {
      provider: 'v8',
      reporter: ['text', 'html'],
      exclude: ['node_modules/', 'dist/'],
    },
  },
})

Worker / WASM

export default defineConfig({
  worker: {
    format: 'es',      // 'es' | 'iife'
    plugins: [],
  },

  // เปิด WASM support (Vite 6+)
  optimizeDeps: {
    exclude: ['my-wasm-module'],
  },
})

เปรียบเทียบ Vite กับ Webpack

ViteWebpack
Dev serverNative ESM (เร็วมาก)Bundle ทั้งหมดก่อน
HMRเร็วมาก (module-level)ช้า (rebundle)
Configง่ายซับซ้อน
Plugin ecosystemเล็กกว่า แต่โตใหญ่มาก
Production buildRollupWebpack
TypeScriptรองรับ built-inต้อง ts-loader

สำหรับ project ใหม่ปี 2024+: Vite คือตัวเลือกแรก เว้นแต่ต้องการ webpack-specific feature