Lesson 27-Vite Environment Variables and Building

Environment Variables and Modes

Environment Variables Basics

Vite supports reading environment variables from .env files, which can be accessed in code via import.meta.env. By default, Vite creates the following types of .env files:

  • .env: Base variables shared across all environments.
  • .env.local: Local overrides for the current environment.
  • .env.[mode]: Variables specific to a build mode.
  • .env.[mode].local: Local overrides specific to a build mode.

Reading Environment Variables

The following properties are available through import.meta.env:

  • import.meta.env.MODE: {string} The mode the application is running in.
  • import.meta.env.BASE_URL: {string} The base URL for deploying the application, determined by the base configuration option.
  • import.meta.env.PROD: {boolean} Indicates whether the application is running in production.
  • import.meta.env.DEV: {boolean} Indicates whether the application is running in development (always the opposite of import.meta.env.PROD).
  • import.meta.env.SSR: {boolean} Indicates whether the application is running on the server.

Environment variables are accessible via the import.meta.env object, which includes all variables read from .env files. For example:

// src/main.js
console.log(import.meta.env.VITE_APP_TITLE);

Here, VITE_APP_TITLE is a variable defined in a .env file, automatically converted to import.meta.env.VITE_APP_TITLE by Vite.

Environment Variable Loading Order

Vite loads environment variables in the following order:

  • .env
  • .env.[mode]
  • .env.local
  • .env.[mode].local

Where [mode] can be development, production, or test. This means variables in .env.development.local will override those in .env with the same name.

Development and Production Modes

Vite supports multiple build modes, with development and production being the most common. In development mode, Vite starts a hot-reloading development server. In production mode, Vite performs code compression, dependency optimization, and other operations to generate deployable static files.

Code Example

Assume the following .env file structure:

  • .env
  • .env.development
  • .env.production
  • .env.development.local
  • .env.production.local

Define base variables in .env:

# .env
VITE_APP_TITLE=My App

Define development-specific variables in .env.development:

# .env.development
VITE_API_URL=http://localhost:3000/api

Define production-specific variables in .env.production:

# .env.production
VITE_API_URL=https://api.example.com

Use these variables in code:

// src/main.js
const title = import.meta.env.VITE_APP_TITLE;
const apiUrl = import.meta.env.VITE_API_URL;

console.log(title); // "My App"
console.log(apiUrl); // "http://localhost:3000/api" in development, "https://api.example.com" in production

Mode Switching

You can switch build modes via the --mode parameter in the command line:

# Development mode
vite

# Production mode
vite build --mode production

Advanced Usage: Conditional Compilation

Vite supports conditional compilation based on environment variables, which is useful for handling logic differences across environments. For example:

if (import.meta.env.MODE === 'production') {
  // Production environment code
} else {
  // Development environment code
}

Building for Production

Vite’s production build process is a critical step for deploying modern frontend projects, involving code compression, resource optimization, dependency management, and performance enhancements.

Understanding Vite’s Build Process

The Vite build process includes the following stages:

  • Dependency Resolution and Optimization: Vite uses ESBuild to pre-build and optimize dependencies, including tree-shaking and module preloading.
  • Code Splitting: Vite automatically splits code based on structure and routes, generating on-demand chunks.
  • Compression and Obfuscation: Production builds enable code compression and obfuscation to reduce file sizes and improve load times.
  • Asset Optimization: Static assets like images and fonts are compressed and converted for optimized network transfer.
  • Manifest Generation: A manifest file is created, listing all generated files and their hashes for cache control and resource location.

Configuring vite.config.js

Build configurations are primarily defined in vite.config.js. Key options include:

  • build.target: Specifies the target environment, e.g., "esnext" or "chrome80".
  • build.cssCodeSplit: Enables or disables CSS code splitting.
  • build.sourcemap: Generates source map files for debugging.
  • build.minify: Specifies the compression method, e.g., "terser" or "esbuild".
  • build.rollupOptions: Customizes Rollup build options, such as code-splitting strategies and plugins.
  • build.assetsDir: Specifies the output directory for static assets.
  • build.lib: Special configuration for building libraries.

Code Example: From Development to Production

Assume a simple Vite project with the following structure:

src/
├── main.js
└── index.html

1. Development Environment

Run Vite in development:

vite

This starts a development server that listens for file changes and performs hot updates.

2. Modify Configuration

Prepare for production by modifying vite.config.js:

// vite.config.js
export default {
  build: {
    target: 'esnext',
    cssCodeSplit: true,
    sourcemap: false,
    minify: 'terser',
    assetsDir: 'static',
    rollupOptions: {
      input: 'src/main.js',
      output: {
        manualChunks(id) {
          if (id.includes('node_modules')) {
            return id.toString().split('node_modules/')[1].split('/')[0].toString();
          }
        },
      },
    },
  },
};

3. Production Build

Run the production build:

vite build

This performs the following:

  • Compresses and optimizes all code and assets.
  • Generates a dist directory containing optimized static files.
  • Creates a manifest.json file for resource location and cache control.

Code Optimization and Performance Improvements

During production builds, Vite automatically applies the following optimizations:

  • Tree-Shaking: Removes unused code and dependencies to reduce bundle size.
  • Code Compression: Uses Terser or ESBuild for code compression and obfuscation.
  • Asset Compression: Compresses static assets like images and fonts.
  • On-Demand Loading: Implements code splitting for on-demand resource loading, speeding up initial page loads.

Deployment and Cache Control

After building, deploy the dist directory to a server. For improved performance, leverage CDNs and browser caching. Use hashes from the manifest.json file in index.html for cache control:

<!-- index.html -->
<script src="/static/js/main.[hash].js"></script>
<link rel="stylesheet" href="/static/css/main.[hash].css">

Static Site Deployment

As a modern frontend build tool, Vite is well-suited for building and deploying static sites. Static sites consist of pre-rendered HTML pages served directly to users without dynamic server-side rendering. This architecture significantly improves loading speed, responsiveness, and reduces server costs.

Steps for Deploying a Static Site with Vite:

1. Build the Project

Before deployment, generate static files using Vite’s build command, which compiles the application into static assets placed in the dist directory.

npm run build
# or
yarn build

2. Configure vite.config.js

Adjust vite.config.js to meet static site deployment needs. For example, if deploying to GitHub Pages or a CDN, set the base option to specify the site’s root path.

// vite.config.js
export default {
  base: '/my-site/', // Specify the path if deploying to a subdirectory
  build: {
    outDir: 'dist', // Output directory
    emptyOutDir: true, // Clear output directory before building
    rollupOptions: {
      input: 'index.html' // Specify entry file
    }
  }
};

3. Deploy to the Target Server

Upload the dist directory’s contents to your server or CDN. Deployment methods depend on the service provider, including:

  • GitHub Pages: Use the gh-pages plugin or manually upload to the gh-pages branch of a GitHub repository.
  • Netlify: Connect your project to Netlify and use Git hooks for automatic deployment.
  • Vercel: Similar to Netlify, with additional customization options.
  • AWS S3: Upload to an S3 bucket configured for static website hosting.
  • Firebase Hosting: Deploy files using the Firebase CLI.

4. Configure Domain and SSL

Optionally, configure a custom domain and SSL certificate on your chosen platform. Most modern static site hosting services provide straightforward methods for associating domains and enabling HTTPS.

5. Test Deployment

After deployment, test the site to ensure everything works correctly. Verify that links function, styles and scripts load properly, and no resources fail to load.

6. Continuous Integration/Continuous Deployment (CI/CD)

Automate deployment with a CI/CD pipeline, triggering builds and deployments on code repository updates. Common CI/CD tools include Jenkins, GitLab CI, CircleCI, and Travis CI.

7. Server-Side Rendering (SSR) or Static Site Generation (SSG)

While Vite is primarily for static sites, it supports server-side rendering (SSR). For dynamic content, use Vite’s SSR features to pre-render pages, which requires additional configuration and server-side support but improves SEO and user experience.

Share your love