vite build

What vite build writes into dist, why generated filenames carry a content hash, and how to check the result with vite preview.

Syntaxvite build [--mode <mode>] [--base <path>] [--outDir <dir>]

During development Vite serves your source files to the browser as native ES modules. A deployed site cannot work that way: a .vue file is not something a browser can execute, and hundreds of separate requests would be slow. vite build is the step that turns the project into static files a web server can hand out.

What it produces

The output directory is dist by default (build.outDir), with generated JavaScript, CSS and imported assets under dist/assets (build.assetsDir). Generated filenames contain a hash of their content, such as index-C9aFHHR_.js. The hash changes only when the content changes, which lets a host cache those files for a long time while a new deploy produces new names. dist is emptied first, because build.emptyOutDir defaults to true.

Running it

In a project from npm create vue@latest, npm run build is a shorthand for two scripts run together: type-check (vue-tsc --build) and build-only (vite build). Calling npx vite build directly produces the same bundle but skips type checking.

Reading the summary

The build prints one line per emitted file with its size and its gzip size, then a total time. It warns when a chunk is larger than 500 kB (build.chunkSizeWarningLimit). That warning is information, not an error.

Checking it

vite preview serves the built dist on port 4173. It is the fastest way to catch a broken base path or a missing asset before a deploy.

Example

Example · vue
<script setup lang="ts">
import logoUrl from '@/assets/logo.svg'

const props = defineProps<{
  label: string
}>()

// import.meta is not available in a template, so read it here.
const homeUrl = import.meta.env.BASE_URL
</script>

<template>
  <a :href="homeUrl" class="logo">
    <!-- :src is shorthand for v-bind:src; both are shown, they are the same -->
    <img v-bind:src="logoUrl" :alt="props.label" width="120" height="32" />
  </a>
</template>

<style scoped>
.logo {
  display: inline-flex;
  align-items: center;
}
</style>

When to use it

  • Confirm a new dependency did not double your bundle size by reading the build summary.
  • Reproduce a "works locally, blank page in production" report with vite preview before touching the server.
  • Set up long-lived cache headers on dist/assets, knowing every filename there is content-hashed.
  • Build the same project for a subdirectory deploy with --base and verify it locally.

More examples

The build output summary

Read this from the bottom up. The gzip column is closer to what a visitor downloads than the raw size, since nearly every host compresses. The hash in each name is the cache key: a deploy where only the CSS changed emits a new CSS filename and leaves the JS filename untouched, so returning visitors re-download only what moved. Reach for this output whenever you want to know whether a dependency you just added actually landed in the bundle.

Example · bash
$ npm run build

> type-check
> vue-tsc --build

> build-only
> vite build

vite v8.0.0 building for production...
✓ 41 modules transformed.
dist/index.html                   0.46 kB | gzip:  0.30 kB
dist/assets/logo-BvYc1xHq.svg     1.10 kB | gzip:  0.62 kB
dist/assets/index-DqTsGk3n.css    4.82 kB | gzip:  1.47 kB
dist/assets/index-C9aFHHR_.js   112.37 kB | gzip: 43.21 kB
✓ built in 1.84s

The scripts the build uses (package.json)

This is the scaffold from npm create vue@latest. run-p (from npm-run-all2) runs type-check and build-only in parallel, so a type error and a bundling error surface in the same run. The longhand equivalent, useful when you want them strictly in order, is npm run type-check && npm run build-only. Knowing the split matters in CI: build-only is the bundle, type-check is the gate.

Example · json
{
  "scripts": {
    "dev": "vite",
    "build": "run-p type-check \"build-only {@}\" --",
    "build-only": "vite build",
    "type-check": "vue-tsc --build",
    "preview": "vite preview"
  }
}

Previewing exactly what you are about to deploy

Use this before every first deploy to a new host. The third command is the one that catches the most common deploy failure: a site built for the site root but served from a subdirectory, which loads index.html and then 404s on every asset. If preview at the real base path works and the host does not, the problem is the host configuration rather than the build.

Example · bash
# Build, then serve dist on http://localhost:4173
npm run build
npm run preview

# Pass flags through npm with --
npm run preview -- --port 5050 --host

# Build a subdirectory deploy and preview it at the same path
npx vite build --base=/app/
npx vite preview --base=/app/

Discussion

  • Be the first to comment on this lesson.