Master production deployment: CDNs, bundlers, minification, caching, and everything needed to ship fast, globally optimized JavaScript applications.
๐ก This lesson covers advanced deployment concepts including build systems (Webpack, Vite), CDN configuration, cache strategies, and production optimization techniques used by major companies.
Shipping a JavaScript app to the world means getting it to load fast, load globally, be secure, be versioned correctly, use caching properly, and serve as few bytes as possible.
Your goal: Max performance, low bandwidth cost, global speed, zero unnecessary code.
A CDN is a global network of servers that stores ("caches") your files and delivers them to users from the closest location. This makes your app load WAY faster globally.
๐ก When a user visits your site, they get the file from the nearest CDN node, NOT your origin server. This reduces latency by hundreds of milliseconds.
CDNs host JavaScript bundles, CSS, images, videos, and sometimes API responses.
Minification removes spaces, newlines, long variable names, unused code, comments, and formatting.
See how minification reduces file size
// ===== Minification Demo =====
// Before minification (readable):
function calculateTotal(price, quantity) {
const subtotal = price * quantity;
const tax = subtotal * 0.1;
return subtotal + tax;
}
// Let's test it!
const total = calculateTotal(100, 5);
console.log("Price: $100, Quantity: 5");
console.log("Total with 10% tax: $" + total);
// After minification (production), this becomes:
// function calculateTotal(e,t){const n=e*t;return n+.1*n}
//
// Typical size reduction: 30-70% sma
...Browsers load faster when 1 big file loads instead of 30 small ones. Bundlers do tons of work:
Fastest, uses esbuild for dev and Rollup for production
Most configurable, huge plugin ecosystem
Best for libraries and SDKs
Extremely fast, written in Go
Tree shaking automatically removes code you import but never use.
See how unused code is removed
// ===== Tree Shaking Demo =====
// Imagine we have a math utilities module:
// math.js exports these functions:
function add(a, b) { return a + b; }
function subtract(a, b) { return a - b; }
function multiply(a, b) { return a * b; }
function divide(a, b) { return a / b; }
// In our app, we only USE add():
const result = add(5, 3);
console.log("Using add(5, 3):", result);
// Tree Shaking Analysis:
console.log("\n๐ฆ What happens in production build:");
console.log("โ add() is INCLUDED (we use
...Instead of one giant bundle, create chunks. Only load what the page needs.
Understand how code splitting works
// ===== Code Splitting Demo =====
// Without code splitting:
// One huge bundle: app.js (500KB)
// User waits for EVERYTHING to load before seeing anything
// With code splitting - separate bundles:
const bundles = {
"home.bundle.js": "50KB",
"dashboard.bundle.js": "150KB",
"profile.bundle.js": "80KB",
"charts.bundle.js": "200KB"
};
console.log("๐ฆ Code-split bundles:");
Object.entries(bundles).forEach(([file, size]) => {
console.log(` ${file}: ${size}`);
});
// Dynamic import s
...Browsers aggressively cache JS files. If you deploy updates but the old file is cached, users see OLD code. Solve this with hashed filenames.
Learn how hashed filenames work
// ===== Hashing & Cache Busting Demo =====
// Production build creates hashed filenames:
const buildOutput = {
files: [
"app.8c1f19a.js", // Hash changes when code changes
"vendor.5a9e02d.js", // Separate vendor bundle
"styles.9fc3a44.css" // CSS also hashed
]
};
console.log("๐ Production build output:");
buildOutput.files.forEach(file => console.log(" " + file));
// When you update your code:
console.log("\n๐ After code update:");
console.log(" OLD: app.8c1f19a.
...Browsers support compressed JS files. CDNs automatically compress your bundles.
Older, still common. ~60-70% compression.
Newest, best compression. ~70-80% smaller.
A 600KB file can become 80KB with Brotli. CDNs like Cloudflare and Vercel handle this automatically.
See Vite build configuration
// ===== Vite Configuration Reference =====
// This is what vite.config.js looks like:
console.log("๐ vite.config.js structure:");
const viteConfig = {
build: {
minify: "terser", // Use Terser for minification
sourcemap: true, // Generate source maps for debugging
rollupOptions: {
output: {
manualChunks: {
vendor: ["lodash", "axios"] // Split vendor code
}
}
}
}
};
console.log(JSON.stringify(viteConfig, null, 2));
conso
...See Webpack build configuration
// ===== Webpack Configuration Reference =====
// This is what webpack.prod.js looks like:
console.log("๐ webpack.prod.js structure:");
const webpackConfig = {
mode: "production",
output: {
filename: "js/[name].[contenthash].js",
clean: true
},
optimization: {
minimize: true,
splitChunks: { chunks: "all" }
},
plugins: ["MiniCssExtractPlugin"]
};
console.log(JSON.stringify(webpackConfig, null, 2));
console.log("\n๐ง Key Webpack features:");
console.log(" โ Product
...These headers decide when browser reloads files, what gets cached, and how long it stays cached.
Understand cache headers
// ===== Cache-Control Headers Demo =====
console.log("๐ฆ Cache-Control Headers Explained:\n");
// For hashed JS/CSS files (app.8c1f19a.js):
console.log("For HASHED files (app.8c1f19a.js):");
console.log(" Cache-Control: public, max-age=31536000, immutable");
console.log(" โ Cache for 1 YEAR");
console.log(" โ NEVER revalidate");
console.log(" โ Hash guarantees uniqueness");
console.log(" โ INSTANT load for returning visitors!");
// For HTML files (index.html):
console.log("\nFor HTML fi
...Push to GitHub โ CI builds your JS โ CI uploads to CDN โ deployment is fully automatic.
Learn about automated deployment
// ===== CI/CD Pipeline Demo =====
// GitHub Actions automatically builds and deploys your app!
console.log("๐ CI/CD Pipeline Steps:\n");
const pipelineSteps = [
"1. Developer pushes code to 'main' branch",
"2. GitHub Actions triggers workflow",
"3. Checkout code from repository",
"4. Setup Node.js environment",
"5. Run: npm install",
"6. Run: npm run build (creates optimized bundle)",
"7. Deploy to CDN (Cloudflare, Vercel, etc.)",
"8. App is live globally in seconds!"
];
pip
...For history mode routing, all routes must serve index.html. Without this rule, refreshing SPA pages will crash.
Understand SPA routing rules
// ===== SPA Rewrite Rules Demo =====
// Without these rules, refreshing /dashboard gives 404!
console.log("๐ง SPA Rewrite Rules by Platform:\n");
const platforms = {
"Netlify": "_redirects file: /* /index.html 200",
"Vercel": 'vercel.json: { "rewrites": [{ "source": "/(.*)", "destination": "/" }] }',
"NGINX": "try_files $uri $uri/ /index.html;",
"Apache": "RewriteRule ^ index.html [L]"
};
Object.entries(platforms).forEach(([platform, rule]) => {
console.log(`${platform}:`);
con
...Large companies REQUIRE these headers for production apps.
Learn about security headers
// ===== HTTP Security Headers Demo =====
// These headers protect your production app!
console.log("๐ Essential Security Headers:\n");
const securityHeaders = [
{
header: "Content-Security-Policy",
purpose: "Prevents XSS attacks",
example: "default-src 'self'; script-src 'self'"
},
{
header: "Strict-Transport-Security",
purpose: "Forces HTTPS",
example: "max-age=31536000; includeSubDomains"
},
{
header: "X-Frame-Options",
purpose: "Prevents clickjack
...Sign up for free to track which lessons you've completed and get learning reminders.