---
name: build-tooling
description: Configure Vite for development and production builds. Use when setting up build pipelines, optimizing bundles, or configuring development servers.
allowed-tools: Read, Write, Edit, Bash, Glob, Grep
---
# Build Tooling Skill
Configure Vite for fast development and optimized production builds.
## Why Vite
| Feature | Benefit |
|---------|---------|
| Native ESM | Instant server start, no bundling in dev |
| Hot Module Replacement | Sub-second updates |
| Rollup-based production | Optimized, tree-shaken bundles |
| Built-in TypeScript | No extra configuration |
| CSS handling | PostCSS, CSS modules, preprocessors |
## Project Structure
```
project/
├── src/
│ ├── main.js # Entry point
│ ├── styles/
│ │ └── main.css
│ └── components/
├── public/ # Static assets (copied as-is)
│ └── favicon.ico
├── index.html # Entry HTML
├── vite.config.js # Vite configuration
└── package.json
```
## Basic Configuration
```javascript
// vite.config.js
import { defineConfig } from 'vite';
import { resolve } from 'path';
export default defineConfig({
// Project root (where index.html is)
root: '.',
// Public base path
base: '/',
// Build output
build: {
outDir: 'dist',
assetsDir: 'assets',
sourcemap: true,
// Rollup options
rollupOptions: {
input: {
main: resolve(__dirname, 'index.html'),
},
},
},
// Development server
server: {
port: 3000,
open: true,
cors: true,
},
// Preview server (for testing production build)
preview: {
port: 4173,
},
});
```
## Multi-Page Application
```javascript
// vite.config.js
import { defineConfig } from 'vite';
import { resolve } from 'path';
export default defineConfig({
build: {
rollupOptions: {
input: {
main: resolve(__dirname, 'index.html'),
about: resolve(__dirname, 'about.html'),
contact: resolve(__dirname, 'contact.html'),
},
},
},
});
```
## CSS Configuration
### PostCSS
```javascript
// vite.config.js
export default defineConfig({
css: {
postcss: './postcss.config.js',
devSourcemap: true,
},
});
```
```javascript
// postcss.config.js
export default {
plugins: {
'postcss-import': {},
'postcss-nesting': {},
autoprefixer: {},
},
};
```
### CSS Modules
```javascript
// vite.config.js
export default defineConfig({
css: {
modules: {
localsConvention: 'camelCase',
generateScopedName: '[name]__[local]___[hash:base64:5]',
},
},
});
```
```javascript
// Usage
import styles from './Component.module.css';
element.className = styles.container;
```
## Asset Handling
### Importing Assets
```javascript
// Import as URL
import logoUrl from './logo.png';
img.src = logoUrl;
// Import as string (small files)
import icon from './icon.svg?raw';
element.innerHTML = icon;
// Import as worker
import Worker from './worker.js?worker';
const worker = new Worker();
```
### Public Directory
Files in `public/` are:
- Copied to build root as-is
- Referenced with absolute paths
- Not processed by Vite
```html
```
## Environment Variables
```bash
# .env
VITE_API_URL=https://api.example.com
VITE_APP_TITLE=My App
# .env.production
VITE_API_URL=https://api.production.com
# .env.development
VITE_API_URL=http://localhost:3001
```
```javascript
// Usage (only VITE_ prefixed variables are exposed)
const apiUrl = import.meta.env.VITE_API_URL;
const mode = import.meta.env.MODE; // 'development' or 'production'
const isDev = import.meta.env.DEV;
const isProd = import.meta.env.PROD;
```
```javascript
// vite.config.js - Custom prefix
export default defineConfig({
envPrefix: 'APP_', // Use APP_ instead of VITE_
});
```
## Code Splitting
### Dynamic Imports
```javascript
// Automatic code splitting
const module = await import('./heavy-module.js');
// Named chunks
const Chart = await import(/* webpackChunkName: "chart" */ './Chart.js');
```
### Manual Chunks
```javascript
// vite.config.js
export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks: {
// Group vendor libraries
vendor: ['lodash', 'axios'],
// Separate large libraries
chart: ['chart.js'],
},
},
},
},
});
```
```javascript
// Or use a function for more control
manualChunks(id) {
if (id.includes('node_modules')) {
return 'vendor';
}
}
```
## Plugins
### Common Plugins
```javascript
// vite.config.js
import { defineConfig } from 'vite';
import legacy from '@vitejs/plugin-legacy';
import { VitePWA } from 'vite-plugin-pwa';
export default defineConfig({
plugins: [
// Support older browsers
legacy({
targets: ['defaults', 'not IE 11'],
}),
// PWA support
VitePWA({
registerType: 'autoUpdate',
manifest: {
name: 'My App',
short_name: 'App',
theme_color: '#ffffff',
},
}),
],
});
```
### Custom Plugin
```javascript
// vite.config.js
function myPlugin() {
return {
name: 'my-plugin',
// Transform HTML
transformIndexHtml(html) {
return html.replace(
/