Moderní tvorba webových aplikací

O webu

Jak Vite sestavuje build

Jak Vite hledá soubory ke zpracování, proč převádí CommonJS na ESM a jak funguje v monorepu.

8 minut

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:

  1. vue z node_modules
  2. App.vue a všechny jeho závislosti
  3. main.css a případné @import v 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:

  1. Analyzuje všechny importy
  2. Provádí tree-shaking (odstraňuje nepoužitý kód)
  3. Vytváří optimalisované chunky
  4. 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.

15 minut

Detekce otevření DevTools

Jak zjistit, že se na stránce otevřely vývojářské nástroje.

13 minut

JavaScript nullundefined

Rozdíly mezi nullundefined v JavaScriptu, kdy je používat a jak se vyhnout běžným chybám.

12 minut

Sleep v JavaScriptu

Jak implementovat sleep/delay funkcionalitu v JavaScriptu pomocí Promiseasync/await

6 minut

Novinky e-mailem

Když budu mít něco opravdu zajímavého, můžu vám to poslat e-mailem

Přidej se k 500+ čtenářům
Jen kvalitní obsah
Žádný spam

Web jecas.cz píše Bohumil Jahoda, kontakt
Seznam všech článků
2013–2026