Skip to main content

2 posts tagged with "Vite"

View all tags

Vite Path Alias Configuration - Why You Need Two Configs

· 2 min read

TL;DR

Vite path aliases require simultaneous configuration in both vite.config.ts and tsconfig.json—neither works alone. Vite handles bundler resolution, TypeScript handles type checking and IDE intellisense.

Problem Symptoms

Only Configured vite.config.ts

// vite.config.ts
import { defineConfig } from 'vite'
import path from 'path'

export default defineConfig({
resolve: {
alias: {
'@': path.resolve(__dirname, './src')
}
}
})

Build runs fine, but IDE shows errors:

Cannot find module '@/components/Button' or its corresponding type declarations.

Only Configured tsconfig.json

// tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
}
}

IDE is happy, but Vite build fails:

[vite] Internal server error: Failed to resolve import "@/services/api"

Root Cause

Two Configs, Two Responsibilities

Config FileOwnerPurpose
vite.config.tsVite/esbuildPath resolution during build
tsconfig.jsonTypeScriptType checking, IDE intellisense

Configuring only one:

  • Vite can build, but IDE shows red lines everywhere, no go-to-definition
  • IDE works, but vite dev / vite build can't find modules

Solution

Complete Configuration (Both Required)

// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import path from 'path'

export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src')
}
}
})
// tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "bundler",
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
},
"include": ["src"]
}

Verify Configuration Works

// src/services/api.ts
export const api = { ... }

// src/App.tsx - Should have go-to-definition, intellisense, and build correctly
import { api } from '@/services/api'

Multiple Aliases Example

// vite.config.ts
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
'@components': path.resolve(__dirname, './src/components'),
'@hooks': path.resolve(__dirname, './src/hooks'),
}
}

// tsconfig.json
"paths": {
"@/*": ["src/*"],
"@components/*": ["src/components/*"],
"@hooks/*": ["src/hooks/*"]
}

FAQ

Q: Why does Vite path alias need two configurations?

A: Vite (based on esbuild/rollup) and TypeScript are independent tools. Vite handles module resolution during bundling, TypeScript handles compile-time type checking and IDE support. They don't share configuration.

Q: Still getting errors after configuration?

A: Restart IDE and Vite dev server. VSCode: Cmd+Shift+P → "TypeScript: Restart TS Server", Terminal: Ctrl+C to restart npm run dev.

Q: path.resolve __dirname error?

A: Make sure to import for ES Module: import path from 'path', or add "type": "module" in package.json. Or use import.meta.url instead of __dirname.

Debugging Frontend Deployment Not Updating on Production

· 3 min read

TL;DR

Frontend code pushed to Git but new feature missing on production? The root cause is usually outdated build artifacts on the server. Compare local and server dist/ directory timestamps to confirm, then run npm run build on the server.

Problem

New button/feature works locally (npm run dev) but not visible on production:

  • Browser refresh doesn't help
  • Clearing browser cache doesn't help
  • Code logic looks correct
  • Git confirms code was pushed

Root Cause

Frontend static files are typically served directly by Nginx:

Git Push → Server git pull → Server npm run build → Nginx serves dist/

The problem is between step 2 and 3: Code was git pulled, but npm run build wasn't executed or failed.

Common scenarios:

  1. Auto-deploy script syncs code but doesn't trigger build
  2. Manual deploy forgot to run build command
  3. Build ran but output to wrong directory

Solution

Step 1: Compare Build Artifact Timestamps

# Local
ls -la dist/assets/ | head -5

# Server
ssh user@server "ls -la /path/to/project/dist/assets/ | head -5"

Output comparison:

# Local (latest build)
Mar 7 22:55 index-28dFGXhX.js ← contains new feature

# Server (old build)
Mar 7 20:18 index-DsFdnylh.js ← missing new feature

Different filenames (hash changed) means content changed, different timestamps means build not synced.

Step 2: Rebuild on Server

ssh user@server "cd /path/to/project && npm run build"

Step 3: Verify Build Artifacts Updated

ssh user@server "ls -la /path/to/project/dist/assets/"

Confirm timestamps and filenames match local.

Step 4: Refresh Page

Since Vite/Webpack generates new filenames with hashes (e.g., index-28dFGXhX.js), index.html references the new file. Users just need a normal refresh, no forced cache clearing needed.

Complete Debug Script

#!/bin/bash
# Save as check-deploy.sh

SERVER="user@server"
PROJECT_PATH="/path/to/project"

echo "=== Latest Local Commit ==="
git log --oneline -1

echo -e "\n=== Latest Server Commit ==="
ssh $SERVER "cd $PROJECT_PATH && git log --oneline -1"

echo -e "\n=== Local Build Time ==="
ls -la dist/assets/ | head -3

echo -e "\n=== Server Build Time ==="
ssh $SERVER "ls -la $PROJECT_PATH/dist/assets/ | head -3"

echo -e "\n=== Server vs Remote Diff ==="
ssh $SERVER "cd $PROJECT_PATH && git fetch origin && git log HEAD..origin/main --oneline"

FAQ

Q: Why is production still showing old code after Git push?

A: Git push only updates source code. Frontend requires npm run build to generate static files. If your deploy process doesn't automatically trigger a build, the server's dist/ directory remains outdated. Nginx serves static files directly and won't auto-execute builds.

Q: Why doesn't clearing browser cache work?

A: The problem isn't browser cache - the server's static files themselves are old. Even with forced refresh, Nginx returns the old JS/CSS files. The correct fix is updating build artifacts on the server.

Q: How to avoid forgetting to rebuild?

A: Two options: 1) Configure CI/CD for automatic builds (e.g., GitHub Actions); 2) Use git hooks on the server to auto-run npm run build after git pull.

Q: Why does Vite add hash to build filenames?

A: Vite adds content hash to bundle filenames by default (e.g., index-28dFGXhX.js). When content changes, hash changes. This is a cache busting strategy ensuring users always get the latest version while maintaining long-term cache capability.