Vite (อ่านว่า "วีท" — มาจากภาษาฝรั่งเศสแปลว่า "เร็ว") คือ Build tool สำหรับ Frontend ที่สร้างโดย Evan You (ผู้สร้าง Vue.js) เปิดตัวในปี 2020 และกลายเป็นมาตรฐาน Frontend tooling ในปี 2026 ที่เร็วกว่า Webpack อย่างมหาศาล ทั้ง Dev server start, HMR (Hot Module Replacement) และ Build time
ทำไม Vite ถึงเร็ว? เพราะแนวคิดพื้นฐานต่างกัน: Webpack bundle ทุกไฟล์ก่อนแล้วค่อย Serve ส่วน Vite ใช้ Native ES Modules ให้ Browser โหลดไฟล์ที่ต้องการทีละตัว ไม่ต้อง Bundle ตอน Dev
Vite vs Webpack vs Parcel vs Turbopack
| Feature | Vite | Webpack | Parcel | Turbopack |
|---|---|---|---|---|
| Dev Server Start | ~200ms | 5-30 วินาที | 3-15 วินาที | ~300ms |
| HMR Speed | <50ms | 200ms-2 วินาที | 200ms-1 วินาที | <50ms |
| Production Build | Rollup (fast) | ช้า-ปานกลาง | ปานกลาง | Next.js only |
| Config | น้อยมาก | ซับซ้อนมาก | Zero config | Next.js config |
| Framework Support | React, Vue, Svelte, Solid, Lit, Qwik | ทุกอย่าง | ทุกอย่าง | Next.js เท่านั้น |
| Plugin System | Rollup-compatible | Webpack loaders | จำกัด | ไม่มี public API |
| Community | ใหญ่มาก (60K+ stars) | ใหญ่ที่สุด | ปานกลาง | Vercel-driven |
| แนะนำปี 2026 | Yes (Default choice) | Legacy projects | Simple projects | Next.js only |
Vite ทำงานอย่างไร?
Development Mode
ใน Development mode Vite ทำงาน 2 ส่วน:
- esbuild Pre-bundling: Dependencies (node_modules) ถูก Bundle ด้วย
esbuild(เขียนด้วย Go — เร็วกว่า JavaScript bundler 10-100 เท่า) แปลง CommonJS/UMD เป็น ESM ครั้งเดียวแล้ว Cache ไว้ - Native ESM Dev Server: Source code ของคุณ ไม่ถูก Bundle เลย Vite serve ไฟล์ตรงๆ ผ่าน HTTP ให้ Browser โหลดผ่าน
<script type="module">เมื่อ Browser request ไฟล์ไหน Vite ก็ Transform เฉพาะไฟล์นั้น (TypeScript → JS, JSX → JS, CSS → injected)
# เปรียบเทียบ:
# Webpack: Bundle ALL files → Start server → Serve bundled file
# (ทุกไฟล์ถูก process ก่อน = ช้า)
#
# Vite: Start server → Browser requests file → Transform on-demand
# (process เฉพาะไฟล์ที่ Browser ต้องการ = เร็วมาก)
Production Mode
ตอน Build สำหรับ Production Vite ใช้ Rollup ไม่ใช่ esbuild เพราะ:
- Rollup มี Tree-shaking ที่ดีกว่า (ลบ Code ที่ไม่ใช้)
- Code splitting ที่ยืดหยุ่นกว่า
- Plugin ecosystem ที่ Mature กว่า
- Output ที่ Compatible กับ Browser เก่ากว่า
สร้างโปรเจกต์ Vite
# === สร้างโปรเจกต์ใหม่ด้วย Vite ===
# React + TypeScript
npm create vite@latest my-react-app -- --template react-ts
cd my-react-app
npm install
npm run dev
# Vue + TypeScript
npm create vite@latest my-vue-app -- --template vue-ts
# Svelte + TypeScript
npm create vite@latest my-svelte-app -- --template svelte-ts
# Solid
npm create vite@latest my-solid-app -- --template solid-ts
# Lit (Web Components)
npm create vite@latest my-lit-app -- --template lit-ts
# Vanilla (ไม่ใช้ Framework)
npm create vite@latest my-vanilla-app -- --template vanilla-ts
# Templates ทั้งหมด:
# vanilla, vanilla-ts, vue, vue-ts, react, react-ts
# react-swc, react-swc-ts, preact, preact-ts
# lit, lit-ts, svelte, svelte-ts, solid, solid-ts, qwik, qwik-ts
vite.config.ts — Configuration
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import path from 'path'
export default defineConfig({
// Plugins
plugins: [react()],
// Dev server
server: {
port: 3000,
open: true, // เปิด Browser อัตโนมัติ
host: true, // Listen ทุก Interface (0.0.0.0)
proxy: { // Proxy API calls ไป Backend
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},
},
},
// Build options
build: {
outDir: 'dist',
sourcemap: true, // สร้าง Source map
minify: 'terser', // หรือ 'esbuild' (เร็วกว่า)
rollupOptions: {
output: {
manualChunks: { // Code splitting
vendor: ['react', 'react-dom'],
ui: ['@mui/material'],
},
},
},
},
// Path aliases
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
'@components': path.resolve(__dirname, 'src/components'),
'@utils': path.resolve(__dirname, 'src/utils'),
},
},
// CSS
css: {
modules: {
localsConvention: 'camelCase',
},
preprocessorOptions: {
scss: {
additionalData: `@import "@/styles/variables.scss";`,
},
},
},
})
CSS Handling ใน Vite
Built-in Support
// Vite รองรับ CSS แบบ Out-of-the-box:
// 1. CSS import ปกติ
import './styles.css'
// 2. CSS Modules (ไฟล์ลงท้ายด้วย .module.css)
import styles from './Button.module.css'
// <button className={styles.primary}>Click</button>
// 3. Sass/SCSS (ติดตั้ง: npm install -D sass)
import './styles.scss'
// 4. Less (ติดตั้ง: npm install -D less)
import './styles.less'
// 5. PostCSS (สร้างไฟล์ postcss.config.js)
// postcss.config.js:
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
Tailwind CSS + Vite
# ติดตั้ง Tailwind CSS
npm install -D tailwindcss @tailwindcss/vite
// vite.config.ts
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [
react(),
tailwindcss(),
],
})
/* src/index.css */
@import "tailwindcss";
/* พร้อมใช้! */
/* <div className="bg-blue-500 text-white p-4 rounded-lg"> */
Asset Handling
// === Vite Asset Handling ===
// 1. Images — import แล้วได้ URL
import logo from './logo.png'
// <img src={logo} alt="Logo" />
// Dev: /src/logo.png
// Build: /assets/logo-abc123.png (hashed)
// 2. JSON — import ได้เลย
import data from './data.json'
console.log(data.name) // ใช้ได้ทันที
// 3. Web Workers
import MyWorker from './worker?worker'
const worker = new MyWorker()
// 4. WASM
import init from './module.wasm?init'
const instance = await init()
// 5. Static assets ใน /public
// ไฟล์ใน /public จะถูก copy ไป root ตอน Build
// /public/favicon.ico → /favicon.ico
// /public/robots.txt → /robots.txt
// 6. Inline assets (เล็กกว่า 4KB จะถูก inline เป็น base64)
// สามารถปรับ threshold:
// vite.config.ts:
build: {
assetsInlineLimit: 4096, // 4KB (default)
}
Environment Variables
# .env files ใน Vite:
# .env # ทุก Environment
# .env.local # ทุก Environment (gitignore)
# .env.development # Development only
# .env.production # Production only
# .env.staging # Custom mode: vite build --mode staging
# ตั้งค่า:
# .env
VITE_API_URL=https://api.example.com
VITE_APP_TITLE=My App
VITE_DEBUG=true
# ใช้ใน Code:
# (เฉพาะตัวแปรที่ขึ้นต้นด้วย VITE_ เท่านั้นที่ Browser เข้าถึงได้)
console.log(import.meta.env.VITE_API_URL)
console.log(import.meta.env.VITE_APP_TITLE)
console.log(import.meta.env.MODE) // 'development' | 'production'
console.log(import.meta.env.DEV) // true ใน Dev
console.log(import.meta.env.PROD) // true ใน Production
# TypeScript support:
# src/vite-env.d.ts
interface ImportMetaEnv {
readonly VITE_API_URL: string
readonly VITE_APP_TITLE: string
}
interface ImportMeta {
readonly env: ImportMetaEnv
}
Vite Plugins ที่ใช้บ่อย
| Plugin | หน้าที่ | ติดตั้ง |
|---|---|---|
| @vitejs/plugin-react | React + Fast Refresh | npm i -D @vitejs/plugin-react |
| @vitejs/plugin-react-swc | React + SWC (เร็วกว่า Babel) | npm i -D @vitejs/plugin-react-swc |
| vite-plugin-pwa | Progressive Web App | npm i -D vite-plugin-pwa |
| vite-plugin-compression | Gzip/Brotli compression | npm i -D vite-plugin-compression |
| unplugin-auto-import | Auto-import functions (ไม่ต้อง import เอง) | npm i -D unplugin-auto-import |
| unplugin-vue-components | Auto-import Vue components | npm i -D unplugin-vue-components |
| vite-plugin-svgr | Import SVG เป็น React component | npm i -D vite-plugin-svgr |
| vite-tsconfig-paths | ใช้ paths จาก tsconfig.json | npm i -D vite-tsconfig-paths |
HMR (Hot Module Replacement)
HMR ของ Vite เร็วกว่า Webpack อย่างมาก เพราะ:
- Webpack HMR: เมื่อไฟล์เปลี่ยน → rebuild dependency graph → re-bundle modules ที่กระทบ → ส่ง update ไป Browser
- Vite HMR: เมื่อไฟล์เปลี่ยน → invalidate เฉพาะ module นั้น → Browser re-fetch เฉพาะ module นั้น ไม่กระทบ modules อื่น
// HMR API (สำหรับ Custom handling)
if (import.meta.hot) {
import.meta.hot.accept((newModule) => {
// Module ถูก Replace แล้ว
console.log('Updated!', newModule)
})
import.meta.hot.dispose((data) => {
// Cleanup ก่อน Module ถูก Replace
data.cleanup = true
})
}
Library Mode
// สร้าง Library ด้วย Vite (เช่น UI component library)
// vite.config.ts
import { defineConfig } from 'vite'
import { resolve } from 'path'
import dts from 'vite-plugin-dts'
export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'src/index.ts'),
name: 'MyLib',
formats: ['es', 'cjs', 'umd'],
fileName: (format) => `my-lib.${format}.js`,
},
rollupOptions: {
external: ['react', 'react-dom'], // ไม่ Bundle peer dependencies
output: {
globals: {
react: 'React',
'react-dom': 'ReactDOM',
},
},
},
},
plugins: [dts()], // Generate .d.ts files
})
SSR with Vite
// === Vite SSR (Server-Side Rendering) ===
// server.js (Express + Vite SSR)
import express from 'express'
import { createServer as createViteServer } from 'vite'
async function createServer() {
const app = express()
const vite = await createViteServer({
server: { middlewareMode: true },
appType: 'custom',
})
app.use(vite.middlewares)
app.use('*', async (req, res) => {
const url = req.originalUrl
const template = await vite.transformIndexHtml(url,
fs.readFileSync('index.html', 'utf-8'))
const { render } = await vite.ssrLoadModule('/src/entry-server.tsx')
const appHtml = await render(url)
const html = template.replace('<!--app-html-->', appHtml)
res.status(200).set({ 'Content-Type': 'text/html' }).end(html)
})
app.listen(3000)
}
createServer()
Vitest — Vite-native Testing
// Vitest ใช้ Config เดียวกับ Vite — ไม่ต้อง Config แยก!
// npm install -D vitest
// vite.config.ts
/// <reference types="vitest" />
import { defineConfig } from 'vite'
export default defineConfig({
test: {
globals: true,
environment: 'jsdom', // หรือ 'happy-dom' (เร็วกว่า)
setupFiles: './src/test/setup.ts',
coverage: {
provider: 'v8',
reporter: ['text', 'json', 'html'],
},
},
})
// src/utils/math.test.ts
import { describe, it, expect } from 'vitest'
import { sum, multiply } from './math'
describe('math utils', () => {
it('should sum numbers', () => {
expect(sum(1, 2)).toBe(3)
})
it('should multiply numbers', () => {
expect(multiply(3, 4)).toBe(12)
})
})
// Run:
// npx vitest # Watch mode
// npx vitest run # Run once
// npx vitest --coverage # With coverage
Performance Optimization
# === Vite Performance Tips ===
# 1. Analyze bundle size
npm install -D rollup-plugin-visualizer
// vite.config.ts
import { visualizer } from 'rollup-plugin-visualizer'
plugins: [
visualizer({ open: true, gzipSize: true }),
]
# 2. Code splitting — แยก Chunk อัตโนมัติ
// React lazy loading
const Dashboard = lazy(() => import('./pages/Dashboard'))
const Settings = lazy(() => import('./pages/Settings'))
# 3. Pre-load critical modules
// <link rel="modulepreload" href="/assets/vendor.js">
# 4. Optimize deps
// vite.config.ts
optimizeDeps: {
include: ['lodash-es', 'react', 'react-dom'], // Pre-bundle
exclude: ['your-local-package'], // ไม่ Pre-bundle
}
# 5. Build target
build: {
target: 'es2020', // ไม่ต้อง polyfill สำหรับ Modern browsers
// หรือ 'esnext' สำหรับ Speed สูงสุด
}
Migration จาก Webpack / Create React App
# === ย้ายจาก CRA (Create React App) มา Vite ===
# 1. ติดตั้ง Vite
npm install -D vite @vitejs/plugin-react
# 2. สร้าง vite.config.ts
# (ดูตัวอย่างข้างบน)
# 3. ย้าย index.html จาก /public ไป Root
# เพิ่ม: <script type="module" src="/src/main.tsx"></script>
# ลบ: %PUBLIC_URL%
# 4. เปลี่ยน scripts ใน package.json
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview"
}
# 5. เปลี่ยน Environment variables
# CRA: REACT_APP_API_URL → Vite: VITE_API_URL
# CRA: process.env.REACT_APP_xxx → Vite: import.meta.env.VITE_xxx
# 6. ลบ react-scripts
npm uninstall react-scripts
# 7. ทดสอบ
npm run dev
สรุป — ทำไมต้อง Vite ในปี 2026
- Dev Server เร็วมาก: Start ใน 200ms แม้โปรเจกต์จะมี 1,000+ ไฟล์ (Webpack ใช้ 10-30 วินาที)
- HMR แทบทันที: แก้ Code แล้วเห็นผลใน Browser ภายใน 50ms ไม่ต้องรอ Rebuild
- Config น้อย: ใช้ได้ทันทีแทบไม่ต้อง Config (Webpack ต้อง Config 100+ บรรทัด)
- รองรับทุก Framework: React, Vue, Svelte, Solid, Lit, Qwik, Vanilla
- Plugin ecosystem: ใช้ Rollup plugins ได้ + Vite-specific plugins อีกมาก
- Built-in features: CSS Modules, PostCSS, TypeScript, JSON import, Web Workers, WASM — ไม่ต้องติดตั้ง Loader
- Vitest: Testing framework ที่ Share config กับ Vite ไม่ต้อง Config แยก
- Community: 60K+ GitHub stars, Default choice ของ Vue, Svelte, SolidStart, Astro, Nuxt, SvelteKit
ถ้าคุณยังใช้ Webpack หรือ Create React App อยู่ ปี 2026 คือเวลาที่ดีที่สุดในการย้ายมา Vite การ Migrate ไม่ยากอย่างที่คิด และความเร็วที่ได้จะทำให้คุณไม่อยากกลับไปใช้ Webpack อีกเลย
