Build & Bundle
This guide covers how to build Naive Admin Max for production deployment.
Build Commands
| Command | Description |
|---|---|
pnpm build | Full build with type checking (vue-tsc -b) + vite build |
pnpm build:only | Build only, skip type checking |
pnpm typecheck | Type checking only (no build output) |
Production Build
The recommended build command for production:
pnpm buildThis runs two steps in sequence:
vue-tsc -b— Strict TypeScript type checking with zero-error policy. Any type error will fail the build.vite build— Production bundle generation with tree-shaking, code splitting, and minification.
TIP
Use pnpm build:only during CI/CD when you run type checks in a separate step, or when you need a quick build for testing.
Build Output
After a successful build, the output is in the dist/ directory:
dist/
├── index.html # Entry HTML file
├── assets/
│ ├── index-[hash].js # Main JavaScript bundle
│ ├── index-[hash].css # Main CSS bundle
│ ├── vendor-[hash].js # Third-party dependencies (code-split)
│ └── ... # Other chunks (lazy-loaded routes)
├── api/ # Static mock data (copied from public/api/)
├── libarchive/ # WebAssembly assets
└── favicon.ico # Site faviconEnvironment Variables
Configure build behavior via environment files:
.env (shared)
VITE_TOKEN_KEY=admin_token
VITE_NEW_TOKEN_KEY=New-Access-Token.env.development
VITE_API_URL= # Empty in dev — uses Vite proxy / current origin
VITE_WITH_CREDENTIALS=false.env.production
VITE_API_URL=https://api.your-domain.com # Your production API server
VITE_WITH_CREDENTIALS=false| Variable | Description |
|---|---|
VITE_API_URL | Backend API base URL (empty for dev to use local mock) |
VITE_TOKEN_KEY | localStorage key for auth token (default: admin_token) |
VITE_NEW_TOKEN_KEY | Response header name for token renewal |
VITE_WITH_CREDENTIALS | Whether to send cookies with cross-origin requests |
Build Optimization
Code Splitting
Vite automatically splits code by route. Each dynamic route becomes a separate chunk loaded on demand:
assets/
├── index-[hash].js # Core framework (~200KB gzip)
├── dashboard-[hash].js # Dashboard page chunk
├── user-[hash].js # User management chunk
├── role-[hash].js # Role management chunk
└── vendor-[hash].js # Shared dependenciesDependency Optimization
Key dependencies and their approximate sizes:
| Package | Size (gzip) |
|---|---|
| Vue 3 | ~40 KB |
| Naive UI | ~150 KB |
| ECharts | ~250 KB (tree-shakeable) |
| Axios | ~5 KB |
| Vue I18n | ~15 KB |
TIP
ECharts is tree-shakeable. Import only the chart types you use to minimize bundle size:
import * as echarts from 'echarts/core'
import { BarChart, LineChart } from 'echarts/charts'
import { GridComponent, TooltipComponent } from 'echarts/components'
import { CanvasRenderer } from 'echarts/renderers'
echarts.use([BarChart, LineChart, GridComponent, TooltipComponent, CanvasRenderer])Auto-Import
The project uses unplugin-auto-import to eliminate manual imports for Vue APIs:
// No need to import ref, computed, watch, etc.
// They are auto-imported by the plugin
const count = ref(0)
const doubled = computed(() => count.value * 2)Type Checking
Run type checks independently:
pnpm typecheckThis uses vue-tsc in build mode (-b) which checks all project references. The build script enforces zero type errors — any type error will cause the build to fail.
Preview Build Locally
Test the production build locally before deploying:
pnpm build
pnpm previewThis serves the dist/ directory on a local HTTP server so you can verify the build output.
Troubleshooting
Build Fails with Type Errors
# Run typecheck separately to identify issues
pnpm typecheckFix all reported type errors before rebuilding.
Large Bundle Size
# Analyze bundle composition
npx vite-bundle-visualizerLook for unexpectedly large dependencies and consider lazy-loading or tree-shaking them.