Files
gt-agent-company/.agents/skills/vite/references/features-env.md
sexygoat 3c62cc1cd1 first
2026-03-31 18:41:52 +08:00

3.1 KiB

name, description
name description
features-env Environment variables, .env files, and modes in Vite

Environment Variables and Modes

Built-in Constants

Available via import.meta.env:

Constant Description
import.meta.env.MODE App mode ('development' or 'production')
import.meta.env.BASE_URL Base URL from base config
import.meta.env.PROD true in production
import.meta.env.DEV true in development
import.meta.env.SSR true in server-side rendering
if (import.meta.env.DEV) {
  console.log('Development mode')
  // Tree-shaken in production
}

Custom Environment Variables

Only variables prefixed with VITE_ are exposed to client code:

# .env
VITE_API_URL=https://api.example.com
DB_PASSWORD=secret  # NOT exposed to client
console.log(import.meta.env.VITE_API_URL)  // "https://api.example.com"
console.log(import.meta.env.DB_PASSWORD)   // undefined

Custom Prefix

export default defineConfig({
  envPrefix: ['VITE_', 'APP_']  // Expose VITE_* and APP_*
})

.env Files

Load order (later has higher priority):

.env                # Always loaded
.env.local          # Always loaded, gitignored
.env.[mode]         # Only in specified mode
.env.[mode].local   # Only in specified mode, gitignored

Variable Expansion

# .env
KEY=123
EXPANDED=test$KEY   # test123
ESCAPED=test\$foo   # test$foo (escaped)

Modes

# Development mode (default for dev)
vite

# Production mode (default for build)
vite build

# Custom mode
vite build --mode staging

Create mode-specific env file:

# .env.staging
VITE_APP_TITLE=My App (staging)
NODE_ENV=production  # Still production build

NODE_ENV vs Mode

Command NODE_ENV Mode
vite build production production
vite build --mode development production development
NODE_ENV=development vite build development production

TypeScript IntelliSense

Create type declarations for custom env variables:

// vite-env.d.ts
interface ImportMetaEnv {
  readonly VITE_APP_TITLE: string
  readonly VITE_API_URL: string
}

interface ImportMeta {
  readonly env: ImportMetaEnv
}

For strict typing (disallow unknown keys):

interface ViteTypeOptions {
  strictImportMetaEnv: unknown
}

HTML Replacement

Use %VARIABLE% syntax in HTML:

<title>%VITE_APP_TITLE%</title>
<p>Mode: %MODE%</p>

Non-existent variables are left as-is (not replaced with undefined).

Loading Env in Config

Env vars are NOT available in vite.config.ts automatically:

import { defineConfig, loadEnv } from 'vite'

export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd(), '')  // '' loads all vars
  
  return {
    define: {
      __APP_ENV__: JSON.stringify(env.APP_ENV)
    }
  }
})

Security Notes

  • Add *.local to .gitignore
  • VITE_* variables end up in client bundle - no secrets
  • Never set envPrefix to '' (exposes everything)