
Jak Vite sestavuje build
Jak Vite hledá soubory ke zpracování, proč převádí CommonJS na ESM a jak funguje v monorepu.
Vite je moderní build nástroj, který se od tradičních bundlerů typu Webpack liší především způsobem, jakým hledá a zpracovává soubory. Pojďme se podívat, jak to celé funguje.
HTML jako vstupní bod
Na rozdíl od Webpacku, kde se definuje JavaScript soubor jako entry point, Vite staví na HTML souborech.
Ve výchozím nastavení Vite použije <root>/index.html jako vstupní bod. V tomto HTML souboru hledá značky:
<script type="module" src="/src/main.js"></script>
Tento přístup je záměrný – HTML je skutečným vstupním bodem webové aplikace a Vite s ním tak i pracuje.
Sledování importů
Jakmile Vite najde vstupní JavaScript soubor, sleduje všechny importy a postupně prochází celý strom závislostí.
To znamená, že Vite nezpracovává všechny soubory ve složce src/, ale pouze ty, které jsou skutečně importovány.
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import './styles/main.css'
createApp(App).mount('#app')
V tomto příkladu Vite zpracuje:
vueznode_modulesApp.vuea všechny jeho závislostimain.cssa případné@importv něm
Soubory, které nikdo neimportuje, se do buildu nedostanou.
Pre-bundling závislostí
Při prvním spuštění dev serveru Vite prochází zdrojový kód a hledá bare importy – tedy importy balíčků z node_modules.
import lodash from 'lodash-es' // bare import
import './utils.js' // relativní import
Pre-bundling řeší dva problémy:
Konverse formátů
Mnoho npm balíčků je distribuováno jako CommonJS nebo UMD. Vite je musí převést na ESM, protože dev server pracuje výhradně s nativními ES moduly.
Jaký je mezi nimi rozdíl?
CommonJS (CJS)
Původní modulový systém Node.js. Používá require() a module.exports:
// math.js (CommonJS)
const PI = 3.14159
function add(a, b) {
return a + b
}
module.exports = { PI, add }
// použití
const math = require('./math')
console.log(math.add(2, 3))
CommonJS moduly se načítají synchronně. Prohlížeče tento formát nativně nepodporují.
UMD (Universal Module Definition)
Hybridní formát kompatibilní s CommonJS, AMD i globálními proměnnými:
// UMD wrapper (zjednodušeně)
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(['dependency'], factory) // AMD
} else if (typeof module === 'object') {
module.exports = factory(require('dependency')) // CommonJS
} else {
root.MyLib = factory(root.Dependency) // globální proměnná
}
}(this, function (dep) {
return { /* ... */ }
}))
UMD vznikl jako universální řešení před standardisací ES modulů. Dnes je považován za legacy formát.
ESM (ES Modules)
Nativní modulový systém JavaScriptu (od ES2015). Používá import a export:
// math.js (ESM)
export const PI = 3.14159
export function add(a, b) {
return a + b
}
// použití
import { PI, add } from './math.js'
console.log(add(2, 3))
ESM moduly se načítají asynchronně a podporují statickou analysu – bundler tak může provést tree-shaking a odstranit nepoužitý kód.
Proč Vite potřebuje konversi
Během vývoje Vite posílá moduly přímo do prohlížeče. Prohlížeče ale rozumí pouze ESM syntaxi (import/export). Pokud nějaký balíček používá require(), prohlížeč ho nedokáže spustit. Proto Vite při pre-bundlingu převádí CommonJS a UMD balíčky na ESM.
Optimalisace HTTP požadavků
Některé ESM balíčky mají stovky interních modulů. Například lodash-es obsahuje přes 600 souborů.
Bez pre-bundlingu by prohlížeč musel stáhnout každý modul zvlášť. Vite je sloučí do jednoho souboru a dramaticky tak sníží počet HTTP požadavků.
Cachování
Výsledky pre-bundlingu se ukládají do node_modules/.vite. Vite znovu prebundluje pouze když:
- Se změní lockfile (
package-lock.json,pnpm-lock.yaml) - Se změní
vite.config.js - Se změní
NODE_ENV
Pro vynucení nového prebundlingu lze použít --force flag.
Více vstupních bodů
Pro aplikace s více stránkami lze nakonfigurovat více HTML souborů:
// vite.config.js
import { resolve } from 'path'
import { defineConfig } from 'vite'
export default defineConfig({
build: {
rollupOptions: {
input: {
main: resolve(__dirname, 'index.html'),
admin: resolve(__dirname, 'admin/index.html'),
},
},
},
})
Vite pak zpracuje oba HTML soubory a jejich závislosti.
Režim knihovny
Pro tvorbu knihoven se HTML jako vstupní bod nehodí. Vite proto nabízí library mode:
// vite.config.js
import { resolve } from 'path'
import { defineConfig } from 'vite'
export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'src/index.js'),
name: 'MojeKnihovna',
fileName: 'moje-knihovna',
},
},
})
V tomto režimu Vite přímo použije zadaný JavaScript soubor jako vstupní bod.
Monorepo a workspaces
Vite umí pracovat s propojenými balíčky v rámci monorepa (pnpm workspaces, npm workspaces, yarn workspaces).
Propojené balíčky
Balíčky ze stejného repozitáře Vite automaticky detekuje a zachází s nimi jako se zdrojovým kódem – neprebundluje je.
To znamená, že změny v propojeném balíčku se okamžitě projeví bez nutnosti rebuildu.
// package.json v apps/web
{
"dependencies": {
"@muj-projekt/ui": "workspace:*",
"@muj-projekt/utils": "workspace:*"
}
}
CommonJS v monorepu
Pokud propojený balíček není v ESM formátu, je potřeba ho explicitně přidat do konfigurace:
// vite.config.js
export default defineConfig({
optimizeDeps: {
include: ['@muj-projekt/legacy-utils'],
},
build: {
commonjsOptions: {
include: [/@muj-projekt\/legacy-utils/, /node_modules/],
},
},
})
HMR v monorepu
Pro správné fungování Hot Module Replacement v monorepu může být potřeba nastavit server.watch:
// vite.config.js
export default defineConfig({
server: {
watch: {
// Sledovat změny i v nadřazených složkách
ignored: ['!**/node_modules/@muj-projekt/**'],
},
},
})
Rollup pod kapotou
Pro produkční build Vite používá Rollup. Ten přebírá vstupní body a:
- Analyzuje všechny importy
- Provádí tree-shaking (odstraňuje nepoužitý kód)
- Vytváří optimalisované chunky
- Minifikuje výstup
Vite přidává předkonfigurované nastavení optimalisované pro moderní prohlížeče, ale veškeré Rollup možnosti jsou dostupné přes build.rollupOptions.
Souhrn
| Co | Jak to Vite řeší |
|---|---|
| Vstupní bod | HTML soubory (výchozí index.html) |
| Hledání souborů | Sledování importů od vstupního bodu |
| npm balíčky | Pre-bundling do node_modules/.vite |
| Workspace balíčky | Zpracovány jako zdrojový kód |
| Produkční build | Rollup s tree-shakingem |
Tento přístup – sledování importů místo skenování složek – zajišťuje, že se zpracují pouze importované soubory. Díky tree-shakingu se navíc z importovaných modulů odstraní nepoužité exporty (funkce, konstanty), pokud nemají vedlejší efekty.
Související články
Jak vkládat 3D objekty na web pomocí Three.js
Které formáty použít, jak vytvářet modely pomocí AI a kdy raději použít obrázek nebo video.
JavaScript null a undefined
Rozdíly mezi null a undefined v JavaScriptu, kdy je používat a jak se vyhnout běžným chybám.
Sleep v JavaScriptu
Jak implementovat sleep/delay funkcionalitu v JavaScriptu pomocí Promise a async/await