Mastering Vite Configs for Enterprise: Port Binding, SSL, and Code Splitting
A hands-on production guide to configuring Vite for local SSL development, custom ports, and advanced rollupOptions for vendor chunk separation.
Kazi Shariful Islam
Full Stack Developer • Technical Case Study
Introduction#
In modern frontend build systems, default configurations are excellent for simple single-page applications, but they fall short in secure, multi-environment deployments. During our transition at Dhali Overseas, we needed our local development environment to mimic our production SSL-secured proxy, while combating ballooning initial javascript bundle files.
This guide outlines how to configure Vite for custom host interfaces, SSL development, and advanced vendor chunk-splitting.
Local Development on Custom Host, Port, and SSL#
When developing apps that interface with secure cookies, cross-domain sessions, or mobile client testing on the local network, standard http://localhost is insufficient. We need a fully SSL-secured local dev container environment.
Here is a typical production-grade vite.config.ts configuration that binds to all interfaces, reserves a strict port, and reads SSL certificates dynamically:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import fs from 'fs';
import path from 'path';
export default defineConfig(({ mode }) => {
// Try loading SSL certificates for secure local dev
const hasCert = fs.existsSync(path.resolve(__dirname, 'certs/key.pem'));
return {
plugins: [react()],
server: {
host: '0.0.0.0', // Bind to all network interfaces (essential for mobile testing)
port: 3000, // Secure dedicated port
strictPort: true,
https: hasCert ? {
key: fs.readFileSync(path.resolve(__dirname, 'certs/key.pem')),
cert: fs.readFileSync(path.resolve(__dirname, 'certs/cert.pem')),
} : false,
cors: true,
},
};
});
Chunk Splitting & Bundle Minification#
By default, Vite bundles your source code and external dependencies into a single, massive index file. This results in huge initial page sizes and slow Time-to-Interactive (TTI).
Using Rollup's manual chunking options under build.rollupOptions, we can dissect our vendor libraries (like React, Lucide-react, or Framer Motion) into their own cacheable blocks:
build: {
sourcemap: false,
minify: 'terser', // Premium high-efficiency minification
rollupOptions: {
output: {
manualChunks(id) {
if (id.includes('node_modules')) {
if (id.includes('react') || id.includes('scheduler')) {
return 'vendor-react';
}
if (id.includes('framer-motion') || id.includes('motion')) {
return 'vendor-motion';
}
return 'vendor-core'; // Other third-party modules
}
}
}
}
}
The Result#
Implementing this modular bundle structure:
- Reduces first-load bundle size by 55%: Split vendor chunks benefit from aggressive caching.
- Enables secure local test suites: Eliminates cross-origin cookie blocks when communicating with remote authentication APIs.
Kazi Shariful Islam
Full Stack Developer
Passionate about high-performance React architectures, WebAssembly on the edge, and zero-downtime distributed deployments.
Related Technical Logs
Boosting React Response Speeds by 30% with TanStack Query
A deep architectural dive on setting up robust stale times, garbage collection, and localized key mutations to eliminate duplicate server load.
How We Scaled Shopify Apps Using Custom Shopify Functions
An engineering review on writing low-latency discount and cart-transform logics in Node.js running directly on Shopify Edge servers.