Vite+ 2026 — Một Toolchain Duy Nhất Thay Thế Webpack, ESLint và Prettier

Posted on: 4/17/2026 6:12:30 PM

Trong nhiều năm, một dự án frontend điển hình cần ít nhất 4-5 công cụ riêng lẻ: Webpack hoặc Vite để build, ESLint để lint, Prettier để format, Jest hoặc Vitest để test, và thêm một loạt plugin để chúng không đánh nhau. Vite+ — ra mắt bởi VoidZero (công ty của Evan You, tác giả Vue.js và Vite) — thay đổi hoàn toàn cục diện này: một toolchain duy nhất quản lý build, test, lint, format, scaffold và cả runtime.

Bài viết này sẽ phân tích kiến trúc bên trong của Vite+, benchmark hiệu năng so với toolchain truyền thống, cách tích hợp với Vue.js, và chiến lược migration thực tế cho dự án production.

1 CLI Thay thế 5+ công cụ riêng lẻ
100x Oxlint nhanh hơn ESLint
30x Oxfmt nhanh hơn Prettier
7.7x Build nhanh hơn với Rolldown

Vấn đề của Toolchain Phân Mảnh

Trước khi hiểu vì sao Vite+ cần tồn tại, hãy nhìn vào thực trạng một dự án Vue.js production điển hình năm 2025:

// package.json — chỉ riêng devDependencies
{
  "devDependencies": {
    "vite": "^7.0.0",
    "@vitejs/plugin-vue": "^5.0.0",
    "vitest": "^3.0.0",
    "@vue/test-utils": "^2.4.0",
    "eslint": "^9.0.0",
    "@eslint/js": "^9.0.0",
    "eslint-plugin-vue": "^9.25.0",
    "typescript-eslint": "^8.0.0",
    "prettier": "^3.3.0",
    "eslint-config-prettier": "^9.1.0",
    "eslint-plugin-prettier": "^5.1.0",
    "typescript": "^5.6.0"
  }
}

Đó là 12 packages chỉ để có build + lint + format + test. Mỗi package có config riêng (vite.config.ts, eslint.config.js, .prettierrc, vitest.config.ts, tsconfig.json), version matrix phức tạp, và conflict rules giữa ESLint với Prettier là bài toán kinh điển mà eslint-config-prettier chỉ giải quyết được phần nào.

Vấn đề thực tế trong CI/CD

Trong pipeline CI của một dự án Vue.js cỡ trung (500 components), ESLint chạy mất 45-90 giây, Prettier thêm 15-20 giây, và Vitest unit test thêm 60-120 giây. Tổng cộng 2-4 phút chỉ cho lint + format + test — trước khi build production bắt đầu. Với Vite+, con số này giảm xuống dưới 30 giây.

Kiến Trúc Bên Trong Vite+

Vite+ không phải là một wrapper đơn giản gọi lần lượt từng tool. Nó là một unified toolchain được xây dựng trên nền tảng chung viết bằng Rust, chia sẻ parser, AST và infrastructure giữa tất cả các thành phần.

graph TD
    CLI["vite+ CLI"]
    CLI --> BUILD["vite build
Rolldown + Vite 8"] CLI --> DEV["vite dev
Vite Dev Server"] CLI --> TEST["vite test
Vitest"] CLI --> LINT["vite lint
Oxlint"] CLI --> FMT["vite fmt
Oxfmt"] CLI --> NEW["vite new
Scaffolding"] CLI --> RUN["vite run
Task Runner"] CLI --> UI["vite ui
DevTools GUI"] SHARED["OXC — Shared Rust Infrastructure
Parser + AST + Resolver + Transformer"] BUILD --> SHARED LINT --> SHARED FMT --> SHARED style CLI fill:#e94560,stroke:#fff,color:#fff style SHARED fill:#2c3e50,stroke:#fff,color:#fff style BUILD fill:#f8f9fa,stroke:#e94560,color:#2c3e50 style DEV fill:#f8f9fa,stroke:#e94560,color:#2c3e50 style TEST fill:#f8f9fa,stroke:#e94560,color:#2c3e50 style LINT fill:#f8f9fa,stroke:#e94560,color:#2c3e50 style FMT fill:#f8f9fa,stroke:#e94560,color:#2c3e50 style NEW fill:#f8f9fa,stroke:#e94560,color:#2c3e50 style RUN fill:#f8f9fa,stroke:#e94560,color:#2c3e50 style UI fill:#f8f9fa,stroke:#e94560,color:#2c3e50

Kiến trúc Vite+ — một CLI, nhiều command, chia sẻ OXC Rust infrastructure

OXC — Trái tim Rust của hệ sinh thái

OXC (The JavaScript Oxidation Compiler) là project open-source viết bằng Rust, cung cấp parser, linter, formatter, transformer và resolver cho JavaScript/TypeScript. Điểm then chốt: tất cả các thành phần của Vite+ (Rolldown, Oxlint, Oxfmt) đều dùng cùng một parser và AST từ OXC — nghĩa là source code chỉ cần parse một lần duy nhất thay vì 3-4 lần như toolchain truyền thống.

Toolchain truyền thống:
  ESLint:   Parse → AST₁ → Lint rules → Report
  Prettier: Parse → AST₂ → Format → Output
  Vite:     Parse → AST₃ → Transform → Bundle

Vite+:
  OXC:      Parse → AST → Lint + Format + Transform + Bundle
                     ↑
              Một lần parse, nhiều lần dùng

Rolldown — Bundler mới thay thế esbuild + Rollup

Vite trước đây dùng esbuild cho development (transform nhanh) và Rollup cho production (tree-shaking tốt). Sự khác biệt giữa hai bundler này tạo ra dev/prod inconsistency — code chạy tốt trong dev nhưng lỗi khi build production. Rolldown giải quyết triệt để bằng cách thay thế cả hai:

Tiêu chíRollup (cũ)esbuild (cũ)Rolldown (mới)
Ngôn ngữJavaScriptGoRust
Vai trò trong ViteProduction buildDev transformCả dev lẫn prod
Tree-shakingXuất sắcCơ bảnXuất sắc
Tốc độ buildChậm (JS-based)Rất nhanhRất nhanh
Rollup plugin compat100%Không~95%
Dev/Prod consistencyKhông đảm bảoĐảm bảo

Benchmark thực tế

Theo VoidZero, production build với Vite 8 + Rolldown nhanh hơn 1.6x đến 7.7x so với Vite 7 (dùng Rollup). Dự án lớn (10,000+ modules) thấy cải thiện rõ rệt nhất vì Rolldown xử lý song song trên nhiều CPU core, trong khi Rollup bị giới hạn bởi single-threaded JavaScript.

Oxlint — Từ 90 Giây Xuống 1 Giây

Oxlint là linter viết bằng Rust, tái hiện lại phần lớn rule set của ESLint với hiệu năng vượt trội. Không cần node_modules, không cần plugin ecosystem phức tạp — Oxlint chạy như một binary đơn.

Benchmark linting trên dự án Vue.js thực tế

Dự ánFilesESLintOxlintTốc độ
Vue SPA nhỏ503.2s0.04s80x nhanh hơn
Vue + Nuxt medium30018s0.2s90x nhanh hơn
Monorepo enterprise2000+90s0.8s112x nhanh hơn

Oxlint JS Plugins — Bridge từ ESLint ecosystem

Từ tháng 3/2026, Oxlint hỗ trợ JS Plugins Alpha — cho phép viết custom lint rules bằng JavaScript, tương tự ESLint plugins. Đây là bước quan trọng cho adoption vì nhiều team có custom rules riêng:

// oxlint-plugin-vue-custom/no-inline-style.js
export default {
  meta: {
    name: "no-inline-style",
    docs: { description: "Cấm inline style trong Vue template" }
  },
  create(context) {
    return {
      JSXAttribute(node) {
        if (node.name.name === "style") {
          context.report({
            node,
            message: "Dùng CSS class thay vì inline style"
          });
        }
      }
    };
  }
};

Khi nào chưa nên bỏ ESLint?

Nếu project phụ thuộc nặng vào type-aware lint rules (rules cần TypeScript type information như @typescript-eslint/no-floating-promises), Oxlint chưa hỗ trợ đầy đủ. Chiến lược an toàn: chạy Oxlint cho rules thông thường (nhanh) → chỉ chạy ESLint cho type-aware rules còn lại.

Oxfmt — Formatting Nhanh 30x

Oxfmt là code formatter viết bằng Rust, compatible phần lớn với Prettier output. Sự khác biệt chính nằm ở tốc độ:

30x Nhanh hơn Prettier
~97% Prettier-compatible output
0 config Zero-config mặc định

Trong Vite+, formatting được tích hợp sẵn qua vite fmt. Không cần .prettierrc, không cần eslint-config-prettier để giải conflict — Oxlint và Oxfmt chia sẻ cùng OXC parser nên chúng không bao giờ conflict với nhau.

Bắt Đầu với Vite+ và Vue.js

Khởi tạo dự án mới

# Cài Vite+ globally
npm install -g vite-plus

# Scaffold dự án Vue.js mới
vite new my-vue-app --template vue-ts

# Cấu trúc sinh ra:
# my-vue-app/
# ├── src/
# │   ├── App.vue
# │   ├── main.ts
# │   └── components/
# ├── vite.config.ts      ← config duy nhất
# ├── package.json
# └── tsconfig.json

Chú ý: không có eslint.config.js, .prettierrc, hay vitest.config.ts riêng. Mọi thứ được cấu hình trong vite.config.ts:

// vite.config.ts — unified config
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],

  // Oxlint config (thay thế eslint.config.js)
  lint: {
    rules: {
      'no-console': 'warn',
      'no-unused-vars': 'error',
      'vue/no-v-html': 'warn'
    },
    ignore: ['dist/**', 'node_modules/**']
  },

  // Oxfmt config (thay thế .prettierrc)
  fmt: {
    printWidth: 100,
    singleQuote: true,
    semi: false
  },

  // Vitest config (thay thế vitest.config.ts)
  test: {
    environment: 'happy-dom',
    coverage: {
      provider: 'v8',
      reporter: ['text', 'lcov']
    }
  }
})

Workflow hàng ngày

# Development
vite dev                    # Dev server với HMR

# Kiểm tra code quality
vite lint                   # Lint toàn project (< 1 giây)
vite lint --fix             # Auto-fix

# Format code
vite fmt                    # Format toàn project
vite fmt --check            # Chỉ kiểm tra, không sửa

# Testing
vite test                   # Chạy unit tests
vite test --coverage        # Với coverage report
vite test --browser         # Browser mode (real DOM)

# Production build
vite build                  # Build với Rolldown

# DevTools GUI
vite ui                     # Mở GUI trong browser
graph LR
    DEV["vite dev"] --> CODE["Viết code"]
    CODE --> LINT["vite lint --fix"]
    LINT --> FMT["vite fmt"]
    FMT --> TEST["vite test"]
    TEST -->|Pass| COMMIT["git commit"]
    TEST -->|Fail| CODE
    COMMIT --> CI["CI Pipeline"]
    CI --> CLINT["vite lint"]
    CLINT --> CFMT["vite fmt --check"]
    CFMT --> CTEST["vite test --coverage"]
    CTEST --> BUILD["vite build"]
    BUILD --> DEPLOY["Deploy"]

    style DEV fill:#e94560,stroke:#fff,color:#fff
    style DEPLOY fill:#4CAF50,stroke:#fff,color:#fff
    style CI fill:#2c3e50,stroke:#fff,color:#fff

Workflow phát triển và CI/CD với Vite+ — một CLI xuyên suốt

Vitest Browser Mode — Test Vue Component Trên Real DOM

Vitest trong Vite+ hỗ trợ Browser Mode — chạy test trực tiếp trên browser thật thay vì jsdom/happy-dom. Điều này đặc biệt quan trọng với Vue components vì jsdom không mô phỏng chính xác CSS, layout và browser APIs.

// src/components/__tests__/UserCard.spec.ts
import { describe, it, expect } from 'vitest'
import { render, screen } from 'vitest-browser-vue'
import UserCard from '../UserCard.vue'

describe('UserCard', () => {
  it('hiển thị avatar và tên user', async () => {
    render(UserCard, {
      props: {
        user: { name: 'Anh Tú', avatar: '/avatar.jpg', role: 'Developer' }
      }
    })

    // Test trên real DOM — CSS computed styles hoạt động chính xác
    await expect.element(screen.getByText('Anh Tú')).toBeVisible()
    await expect.element(screen.getByRole('img')).toHaveAttribute('src', '/avatar.jpg')
  })

  it('hiển thị badge cho admin', async () => {
    render(UserCard, {
      props: {
        user: { name: 'Admin', avatar: '/admin.jpg', role: 'admin' }
      }
    })

    const badge = screen.getByTestId('admin-badge')
    // Trên real DOM, có thể test cả CSS
    await expect.element(badge).toBeVisible()
  })
})

Khi nào dùng Browser Mode?

Dùng Browser Mode cho component tests cần kiểm tra visual behavior, CSS, layout, hoặc browser APIs (IntersectionObserver, ResizeObserver, Canvas). Dùng happy-dom cho unit tests thuần logic (composables, stores, utilities) — nhanh hơn vì không cần spawn browser.

So Sánh Với Các Toolchain Khác

Tiêu chíVite+BiomeTurbopack + ESLintToolchain truyền thống
BuildRolldown (Rust)Không có bundlerTurbopack (Rust)Webpack/Rollup (JS)
LintOxlint (Rust)Biome (Rust)ESLint (JS)ESLint (JS)
FormatOxfmt (Rust)Biome (Rust)Prettier (JS)Prettier (JS)
TestVitestKhông cóJestJest/Vitest
Scaffoldvite newKhông cócreate-next-appcreate-vite
Vue.js supportFirst-classCó (lint/fmt)KhôngQua plugins
Unified configvite.config.tsbiome.jsonNhiều fileNhiều file
Shared parserOXC (1 lần parse)Có (1 lần parse)KhôngKhông

Vite+ vs Biome — lựa chọn nào?

Biome là lựa chọn tốt nếu bạn chỉ cần lint + format mà không quan tâm đến build/test. Biome v2 có type-aware rules mà Oxlint chưa có. Nhưng nếu bạn đã dùng Vite cho build (đặc biệt là dự án Vue/Nuxt), Vite+ cho trải nghiệm tích hợp trọn gói hơn — một config, một CLI, một version matrix.

Migration Từ Toolchain Truyền Thống

Quá trình migration có thể thực hiện từng bước thay vì big-bang. Dưới đây là chiến lược đã được kiểm chứng:

graph TD
    S1["Bước 1: Nâng cấp Vite 7 → 8"]
    S2["Bước 2: Cài Vite+, giữ ESLint/Prettier"]
    S3["Bước 3: Chạy song song Oxlint + ESLint"]
    S4["Bước 4: Migrate lint rules sang Oxlint"]
    S5["Bước 5: Thay Prettier bằng Oxfmt"]
    S6["Bước 6: Gỡ ESLint + Prettier"]

    S1 --> S2 --> S3 --> S4 --> S5 --> S6

    style S1 fill:#f8f9fa,stroke:#e94560,color:#2c3e50
    style S2 fill:#f8f9fa,stroke:#e94560,color:#2c3e50
    style S3 fill:#f8f9fa,stroke:#e94560,color:#2c3e50
    style S4 fill:#f8f9fa,stroke:#e94560,color:#2c3e50
    style S5 fill:#f8f9fa,stroke:#e94560,color:#2c3e50
    style S6 fill:#e94560,stroke:#fff,color:#fff

Chiến lược migration từng bước — giảm rủi ro, giữ CI/CD ổn định

Bước 1-2: Nâng cấp và cài đặt

# Nâng cấp Vite
npm install vite@8 @vitejs/plugin-vue@latest

# Cài Vite+ (không gỡ ESLint/Prettier ngay)
npm install -g vite-plus

Bước 3: Chạy song song — Dual Linter Pattern

Chiến lược an toàn nhất: chạy Oxlint cho các rules phổ biến (nhanh), rồi chạy ESLint cho type-aware rules còn lại:

// package.json scripts
{
  "scripts": {
    "lint": "vite lint && eslint --rule '{no-console: off, no-unused-vars: off}' src/",
    "lint:fast": "vite lint",
    "lint:full": "npm run lint"
  }
}

Tắt các rules trong ESLint mà Oxlint đã cover → ESLint chỉ chạy rules riêng (ít hơn) → tổng thời gian giảm đáng kể.

Bước 4-6: Migrate hoàn toàn

# Kiểm tra rule coverage
vite lint --report-eslint-diff  # Xem rules nào Oxlint đã cover

# Khi confident, gỡ ESLint + Prettier
npm uninstall eslint eslint-plugin-vue @eslint/js \
  typescript-eslint prettier eslint-config-prettier \
  eslint-plugin-prettier

# Xóa config files cũ
rm eslint.config.js .prettierrc .prettierignore

Lưu ý khi migration

Oxfmt có thể format hơi khác Prettier ở một số edge cases (ví dụ: trailing comma trong function parameters, cách wrap JSX). Chạy vite fmt toàn project và commit diff format riêng trước khi merge bất kỳ feature branch nào — tránh format noise trong code review.

Tích Hợp CI/CD Pipeline

Một trong những lợi ích lớn nhất của Vite+ là đơn giản hóa CI/CD pipeline xuống còn vài dòng:

# .github/workflows/ci.yml
name: CI
on: [push, pull_request]

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: 'npm'

      - run: npm ci
      - run: vite lint              # Lint (< 1s)
      - run: vite fmt --check       # Format check (< 1s)
      - run: vite test --coverage   # Test + coverage
      - run: vite build             # Production build

      - uses: actions/upload-artifact@v4
        with:
          name: dist
          path: dist/

So sánh thời gian CI pipeline trên cùng một dự án Vue.js (800 files, 200 components):

Giai đoạnToolchain cũVite+Cải thiện
Install dependencies35s25sÍt deps hơn
Lint45s (ESLint)0.5s (Oxlint)90x
Format check12s (Prettier)0.4s (Oxfmt)30x
Unit tests65s (Vitest)60s (Vitest)~1x
Production build28s (Rollup)8s (Rolldown)3.5x
Tổng~185s~94s~2x nhanh hơn

Vite+ Trong Monorepo

Với command vite run, Vite+ hoạt động như task runner cho monorepo — tương tự Turborepo nhưng tích hợp sẵn:

# Chạy lint trên tất cả packages
vite run lint --filter=packages/*

# Build theo dependency order
vite run build --filter=packages/* --topo

# Test chỉ packages bị ảnh hưởng bởi changes
vite run test --filter=...changed
monorepo/
├── packages/
│   ├── ui/               ← Vue component library
│   │   ├── src/
│   │   └── vite.config.ts
│   ├── web/              ← Nuxt app
│   │   ├── src/
│   │   └── vite.config.ts
│   └── shared/           ← Shared utilities
│       ├── src/
│       └── vite.config.ts
└── vite.config.ts        ← Root config (shared settings)

Tương Thích Với Vue Ecosystem

Vite+ được thiết kế để hoạt động liền mạch với toàn bộ hệ sinh thái Vue:

Tool/FrameworkTrạng tháiGhi chú
Vue 3.6 (Vapor Mode)✅ Hỗ trợ đầy đủRolldown xử lý Vapor output tối ưu
Nuxt 4✅ Hỗ trợ đầy đủNuxt 4 đã dùng Vite 8 natively
Pinia 3✅ Không thay đổiStore logic không ảnh hưởng
Vue Router 4✅ Không thay đổiRouting không ảnh hưởng
TanStack Query Vue✅ Không thay đổiData fetching không ảnh hưởng
VueUse✅ Không thay đổiComposables không ảnh hưởng
Vuetify / PrimeVue✅ CompatibleRolldown tương thích Rollup plugins
Storybook⚠️ Đang migrationStorybook 9 sẽ dùng Vite 8

Production Tips

Tip 1: Dùng vite ui cho debugging

vite ui mở DevTools GUI trong browser, cho phép inspect module graph, xem bundle analysis, chạy test từng file, và kiểm tra lint results — tất cả trong một giao diện trực quan. Đặc biệt hữu ích khi debug bundle size hoặc tìm circular dependencies.

Tip 2: Cache Rolldown trong CI

Rolldown hỗ trợ persistent cache. Thêm node_modules/.vite vào CI cache để build lần sau nhanh hơn 2-3x cho incremental changes.

Tip 3: Pre-commit hook nhẹ

Thay vì chạy lint toàn project trong pre-commit (chậm), dùng vite lint --changedvite fmt --changed để chỉ check files đã thay đổi — thường dưới 100ms.

Roadmap và Tương Lai

Q1 2026
Vite+ Alpha open source — scaffold, dev, build, lint, fmt cơ bản hoạt động. Rolldown ổn định cho production builds.
Q2 2026
Oxlint JS Plugins Alpha — cho phép viết custom rules bằng JavaScript. Type-aware lint rules đang phát triển.
Q3 2026 (dự kiến)
Vite+ Beta — vite run cho monorepo, Browser Mode testing ổn định, Storybook 9 integration.
Q4 2026 (dự kiến)
Vite+ 1.0 stable — type-aware lint rules trong Oxlint, full Rollup plugin compatibility trong Rolldown.

Kết Luận

Vite+ đánh dấu sự chuyển mình của JavaScript toolchain từ "nhiều công cụ rời rạc" sang "một nền tảng hợp nhất". Với OXC Rust infrastructure làm nền tảng, mỗi thành phần (build, lint, format, test) không chỉ nhanh hơn đơn lẻ mà còn nhanh hơn tổng thể nhờ chia sẻ parser và AST.

Đối với các team đang dùng Vue.js/Nuxt, Vite+ là upgrade tự nhiên nhất: cùng tác giả (Evan You), first-class Vue support, và backward-compatible với Vite ecosystem hiện tại. Migration có thể làm từng bước, không cần rewrite config hay đổi workflow.

Nếu bạn đang khởi đầu dự án Vue mới trong năm 2026, vite new my-app --template vue-ts là tất cả những gì cần để có một setup production-ready với build, lint, format và test — zero-config, one CLI.

Tham Khảo