Agent skill
personal-vite-jsx-caching-fix
Troubleshoot Vite JSX parsing errors caused by stale compiled files in src directories
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/personal-vite-jsx-caching-fix
SKILL.md
Vite JSX Caching Fix
Troubleshooting guide for "Failed to parse source for import analysis because the content contains invalid JS syntax" errors in Vite projects.
Problem Description
This error occurs when compiled .js, .d.ts, and .map files accumulate in src/ directories. Vite picks up these stale compiled files instead of the fresh TypeScript sources, leading to JSX parsing failures.
Error message:
[plugin:vite:import-analysis] Failed to parse source for import analysis because the content contains invalid JS syntax. If you are using JSX, make sure to name the file with the .jsx or .tsx extension.
When This Occurs
- After linters or build tools accidentally compile files into
src/instead ofdist/ - After IDE plugins auto-compile TypeScript
- After incorrect tsconfig
outDirsettings - After running
tscfrom wrong directory
Identifying the Problem
Search for compiled files in src directories:
# Count compiled files in src directories
find packages/*/src -name "*.js" -o -name "*.js.map" -o -name "*.d.ts" -o -name "*.d.ts.map" 2>/dev/null | wc -l
# List all compiled files
find packages/*/src \( -name "*.js" -o -name "*.js.map" -o -name "*.d.ts" -o -name "*.d.ts.map" \) -type f
# Check specific package
find packages/dashboard-frontend/src -name "*.js" 2>/dev/null
Complete Cleanup Procedure
Step 1: Stop dev server
./run.sh dev stop
Step 2: Remove compiled files from ALL src directories
find packages/*/src \( -name "*.js" -o -name "*.js.map" -o -name "*.d.ts" -o -name "*.d.ts.map" \) -type f -delete
Step 3: Clear Vite cache
rm -rf node_modules/.vite packages/*/node_modules/.vite
Step 4: Clear Turbo cache (optional but recommended)
rm -rf .turbo packages/*/.turbo
Step 5: Reinstall dependencies (if issues persist)
pnpm install --force
Verification Steps
- Confirm no compiled files remain:
find packages/*/src -name "*.js" 2>/dev/null | wc -l # Should be 0
- Test module import speed (should be < 1 second):
cd packages/dashboard && node --import tsx -e "
console.time('import');
import('./src/server/index.js').then(() => console.timeEnd('import'));
"
- Start dev server and verify it starts within 30 seconds:
./run.sh dev
Prevention Strategies
1. Add to .gitignore
Ensure these patterns are in your root .gitignore:
# Compiled output in src directories (should never happen)
packages/*/src/**/*.js
packages/*/src/**/*.js.map
packages/*/src/**/*.d.ts
packages/*/src/**/*.d.ts.map
!packages/*/src/**/*.config.js
2. Verify tsconfig.json
Each package's tsconfig.json should have:
{
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
}
}
3. Pre-commit hook check
Add a check to your pre-commit hook:
# Fail if compiled files exist in src/
if find packages/*/src -name "*.js" -o -name "*.d.ts" 2>/dev/null | grep -q .; then
echo "ERROR: Compiled files found in src directories!"
exit 1
fi
Orphaned Processes (Dashboard Running but Not Responding)
Sometimes after cleanup, the dashboard process shows as "running" but the API is unreachable (connection refused on port 4098). The logs show successful startup but nothing is actually listening.
Symptoms
./run.sh dev statusshows Dashboard API as "running" but endpoint as "unhealthy"curl http://localhost:4098/api/healthreturns connection refusedlsof -i :4098shows nothing listening- Logs show "Dashboard running" and "Dashboard started successfully"
Diagnosis
# Check if process is running but not bound to port
ps aux | grep "dashboard\|4098" | grep -v grep
# Check if anything is listening on the port
lsof -i :4098
# Check for multiple dashboard processes (indicates orphans)
pgrep -f "tsx.*src/main.ts" | wc -l # Should be 1, not more
Root Causes
- tsx watch mode not exiting cleanly - The
tsx watchcommand spawns child processes that may not receive SIGTERM properly when the parent is killed - Crypto mismatch causing the server to crash after logging startup (see
personal-crypto-secrets-managementskill) - Multiple dev sessions - Starting
./run.sh devin multiple terminals without stopping the first - Interrupted stop - Pressing Ctrl+C during
./run.sh dev stopbefore cleanup completes
How dev stop Works
The ./run.sh dev stop command has built-in cleanup:
- Kills registered PIDs from
.dev-pids/directory - Kills child processes recursively
- Searches for orphaned tsx processes matching known patterns
- Checks ports and kills any process still holding them
However, manual intervention is needed when:
- tsx processes were started outside of
run.sh - The PID files were deleted but processes remained
- Node processes are in a defunct/zombie state
Detecting a Failed Stop
After running ./run.sh dev stop, verify cleanup succeeded:
# Should show "All instance 0 ports are free"
./run.sh dev stop
# Verify no tsx dashboard processes remain
pgrep -f "tsx.*dashboard" && echo "ORPHANS FOUND" || echo "Clean"
# Verify ports are free
lsof -i :4098 -i :5173 -i :4097 -i :4099 | grep LISTEN && echo "PORTS IN USE" || echo "Ports free"
Recovery
Step 1: Try clean stop first
./run.sh dev stop
Step 2: Check if stop was successful
# Count remaining tsx processes (should be 0)
pgrep -f "tsx.*src/main.ts" | wc -l
Step 3: If orphans remain, kill them
# Kill tsx processes related to dashboard
pkill -f "tsx.*src/main.ts"
# Kill any process on dashboard port
lsof -ti :4098 | xargs kill -9 2>/dev/null
# Nuclear option: kill all tsx watch processes
pkill -f "tsx.*watch"
Step 4: Wait for processes to exit (important!)
# Give processes time to clean up
sleep 2
# Verify they're gone
pgrep -f "tsx.*src/main.ts" || echo "All tsx processes terminated"
Step 5: Restart cleanly
./run.sh dev
If the problem persists
Check for crypto/secrets errors in the logs:
grep -i "error\|crypto\|decrypt" logs/instance-0/dashboard-dev.log | tail -20
If you see "Unsupported state or unable to authenticate data", the secrets encryption key has changed. See the personal-crypto-secrets-management skill.
Related Issues
-
Slow dashboard startup: If the dashboard takes 60+ seconds to start, check if heavy SDKs like
oci-sdkare being imported at module level. Use dynamicimport()for lazy-loading. -
Module resolution errors: After cleanup, you may need to rebuild dependent packages:
pnpm run build
- 502 Bad Gateway after restart: Often caused by orphaned processes or crypto key mismatch. Follow the orphaned processes recovery steps above.
Didn't find tool you were looking for?