jvinhit//lab

Search posts

Type to search across journal entries.

navigate open esc close

Vite · Part 12 — Performance, Capstone & Migration

Speed up dev and build, assemble a production-grade capstone vite.config.ts from the whole series, and migrate off Webpack or CRA step by step — with the concept-by-concept translation table. With a capstone config & migration explorer.

Eleven parts, and you now understand Vite from the native-ESM dev server to Rolldown production builds and the Environment API {Mười một phần, và giờ bạn hiểu Vite từ dev server ESM native tới build production Rolldown và Environment API}. This finale ties it together: a performance checklist, a capstone config, and a concrete migration path off Webpack/CRA {Phần kết buộc tất cả lại: danh sách hiệu năng, một config capstone, và đường di trú cụ thể khỏi Webpack/CRA}.

Assemble the capstone config and study the migration map {Lắp ráp config capstone và nghiên cứu bản đồ di trú}:


1. Keep dev fast {Giữ dev nhanh}

Vite is fast by default, but large apps can still slow down {Vite nhanh mặc định, nhưng app lớn vẫn có thể chậm}:

  • Tune optimizeDepsinclude deps that get discovered late to avoid mid-session re-optimization reloads {include dep bị phát hiện trễ để tránh reload re-optimize giữa phiên}.
  • Avoid barrel files — a giant index.ts re-exporting everything forces Vite to pull in modules you didn’t use {Tránh barrel file — index.ts khổng lồ re-export mọi thứ buộc Vite kéo vào module bạn không dùng}.
  • Try the experimental full-bundle dev mode — Vite 8’s --experimentalBundle bundles in dev for very large projects (≈3× faster startup, fewer requests) {Thử full-bundle dev mode thử nghiệm — --experimentalBundle của Vite 8 bundle khi dev cho dự án rất lớn (≈3× nhanh hơn, ít request hơn)}.
  • Warm up frequently-used entry files with server.warmup {Làm nóng file entry hay dùng với server.warmup}.

2. Keep builds fast & lean {Giữ build nhanh & gọn}

  • Rolldown already makes builds 10–30× faster than the old path — you get this for free in Vite 8 {Rolldown đã làm build nhanh hơn 10–30× — bạn nhận miễn phí ở Vite 8}.
  • Measure with rollup-plugin-visualizer before optimizing — same discipline as the Webpack series {Đo bằng rollup-plugin-visualizer trước khi tối ưu}.
  • Split a vendor chunk so dependencies cache across deploys {Tách chunk vendor để dependency cache qua các deploy}.
  • Right-size build.target — don’t transpile down to ancient browsers you don’t support {Chọn đúng build.target — đừng transpile xuống trình duyệt cổ bạn không hỗ trợ}.

3. The capstone config {Config capstone}

Here’s a production-ready config that pulls the series together {Đây là config sẵn-sàng-production gom cả series}:

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { fileURLToPath, URL } from "node:url";

export default defineConfig({
  plugins: [react()], // Part 5: Fast Refresh

  resolve: {
    alias: { "@": fileURLToPath(new URL("./src", import.meta.url)) }, // Part 2
  },

  server: {
    proxy: {
      "/api": { target: "http://localhost:8080", changeOrigin: true }, // Part 2
    },
  },

  build: {
    target: "baseline-widely-available", // Part 10
    sourcemap: true, // Part 10
    rollupOptions: {
      output: { manualChunks: { vendor: ["react", "react-dom"] } }, // Part 10
    },
  },
});
// package.json — Vite doesn't type-check, so gate the build
{
  "scripts": {
    "dev": "vite",
    "build": "tsc --noEmit && vite build",
    "preview": "vite preview"
  }
}

That tsc --noEmit && is the one thing people forget — Vite ships fast by not type-checking (Part 3), so you must do it yourself in the build/CI {tsc --noEmit && đó là thứ người ta hay quên — Vite nhanh nhờ không type-check (Phần 3), nên bạn phải tự làm trong build/CI}.


4. Migrating from Webpack / CRA {Di trú từ Webpack / CRA}

The reassuring truth: the concepts transfer directly {Sự thật trấn an: khái niệm chuyển giao trực tiếp}. Everything you learned in the Webpack series has a Vite equivalent {Mọi thứ bạn học trong series Webpack đều có cái tương đương trong Vite}:

Webpack / CRAVitePart
entry: ./src/index.jsindex.html + <script type="module">1
webpack.config.jsvite.config.ts2
babel-loader / ts-loaderbuilt-in (Oxc)3
css-loader + style-loaderbuilt-in CSS6
file-loader / url-loaderasset imports + ?url/?raw7
DefinePlugindefine / import.meta.env8
process.env.REACT_APP_*import.meta.env.VITE_*8
splitChunksmanualChunks / advancedChunks10
webpack-dev-server + HMR pluginbuilt-in dev server + HMR3, 5
custom loaderplugin transform hook9

5. A migration order that minimizes pain {Thứ tự di trú giảm đau}

  1. Scaffold a fresh Vite project (npm create vite@latest) and copy your src/ in {Dựng dự án Vite mới và copy src/ vào}.
  2. Move index.html to the root and add <script type="module" src="/src/main.tsx"> {Chuyển index.html ra gốc và thêm script module}.
  3. Rename env vars: REACT_APP_XVITE_X, and process.env.Ximport.meta.env.VITE_X {Đổi tên env var}.
  4. Swap any require() for import; fix CommonJS-only dependencies {Đổi require() sang import; sửa dependency chỉ-CommonJS}.
  5. Replace loaders with Vite built-ins or plugins (most just disappear) {Thay loader bằng built-in hoặc plugin của Vite (đa số biến mất)}.
  6. Run, fix import paths & aliases, then delete the Webpack config {Chạy, sửa đường dẫn import & alias, rồi xóa config Webpack}.

For CRA specifically, tools like vite codemods exist, but the manual path above is reliable and teaches you the project {Riêng CRA, có công cụ như codemod vite, nhưng đường thủ công trên đáng tin và giúp bạn hiểu dự án}.


6. When not to migrate {Khi không nên di trú}

Be honest {Thành thật}:

  • A large, stable Webpack config that works and isn’t slowing the team {Một config Webpack lớn, ổn định, đang chạy tốt và không làm chậm team}.
  • Heavy reliance on Webpack Module Federation (Vite has options via plugins, but Webpack’s is the most mature) {Phụ thuộc nặng vào Webpack Module Federation}.
  • Niche Webpack loaders/plugins with no Vite equivalent {Loader/plugin Webpack ngách không có tương đương Vite}.

Migrate when dev startup or build speed hurts daily and your stack is mainstream — which is most apps {Di trú khi khởi động dev hoặc tốc độ build gây đau hằng ngày và stack phổ thông — tức đa số app}.


7. Exercises {Bài tập}

1. Your migrated app builds and runs but type errors slip through to production. What’s missing from the build script? {App di trú build và chạy nhưng lỗi kiểu lọt ra production. Build script thiếu gì?}

Solution {Lời giải}

tsc --noEmit before vite build — Vite doesn’t type-check, so CI/build must run the compiler separately {tsc --noEmit trước vite build — Vite không type-check, nên CI/build phải chạy compiler riêng}.

2. After migrating from CRA, process.env.REACT_APP_API is undefined. What’s the Vite equivalent and the required change? {Sau di trú từ CRA, process.env.REACT_APP_APIundefined. Tương đương Vite và thay đổi cần thiết?}

Solution {Lời giải}

Rename the var to VITE_API in .env and read import.meta.env.VITE_API in code {Đổi tên biến thành VITE_API trong .env và đọc import.meta.env.VITE_API trong code}.

3. Your team relies heavily on Webpack Module Federation across many independently deployed apps. Migrate to Vite now? {Team phụ thuộc nặng vào Webpack Module Federation qua nhiều app deploy độc lập. Di trú sang Vite ngay?}

Solution {Lời giải}

Probably not yet — Webpack’s Module Federation is the most mature. Stay unless dev/build speed is a serious, daily problem and the federation story on your target tool is solid {Có lẽ chưa — Module Federation của Webpack trưởng thành nhất. Ở lại trừ khi tốc độ dev/build là vấn đề nghiêm trọng hằng ngày}.

Stretch {Nâng cao}: in the explorer, reach a 90+ readiness score on the capstone, then switch to the migration tab and map each enabled technique back to the Webpack concept it replaces {trong explorer, đạt điểm 90+ ở capstone, rồi chuyển tab di trú và ánh xạ mỗi kỹ thuật đã bật về khái niệm Webpack nó thay}.


Key takeaways {Điểm chính}

  • Keep dev fast with optimizeDeps tuning, fewer barrels, and (for huge apps) bundled dev mode {Giữ dev nhanh bằng chỉnh optimizeDeps, ít barrel, và (app lớn) dev mode bundle}.
  • The capstone config is the whole series assembled — and tsc --noEmit && vite build is non-negotiable {Config capstone là cả series gom lại — và tsc --noEmit && vite build là bắt buộc}.
  • Migration concepts map 1:1 from Webpack/CRA — loaders mostly disappear {Khái niệm di trú ánh xạ 1:1 từ Webpack/CRA — loader đa phần biến mất}.
  • Migrate for dev/build speed on mainstream stacks; stay for mature Module Federation and niche setups {Di trú vì tốc độ dev/build trên stack phổ thông; ở lại vì Module Federation trưởng thành và thiết lập ngách}.
  • You now understand bundlers and dev servers, not just Vite {Giờ bạn hiểu bundler và dev server, không chỉ Vite}.

Series complete {Hoàn thành series}

From “why is my dev server instant?” to a production capstone, custom plugins, the Environment API, and a migration plan — you’ve gone from Vite user to Vite operator {Từ “vì sao dev server tức thì?” tới capstone production, plugin tùy chỉnh, Environment API, và kế hoạch di trú — bạn đã đi từ người dùng Vite thành người vận hành Vite}. Pair it with the Webpack series and you understand the entire modern build-tool landscape {Ghép với series Webpack và bạn hiểu toàn cảnh công cụ build hiện đại}.