Enable source map support for better stack traces
📦 Node.js-> Command Line
✨ The Prompt Phrase
node --enable-source-maps app.js
💻 Code Preview
📦 All-in-One Code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Enable source map support for better stack traces - Interactive Tutorial</title>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600;700;900&family=Fira+Code:wght@400;500;600&display=swap" rel="stylesheet">
<style>
:root {
--bg-primary: #0a0e27;
--bg-secondary: #151932;
--bg-card: #1e2139;
--accent-purple: #a855f7;
--accent-blue: #3b82f6;
--accent-green: #10b981;
--accent-red: #ef4444;
--accent-yellow: #f59e0b;
--accent-pink: #ec4899;
--accent-cyan: #06b6d4;
--accent-indigo: #6366f1;
--text-primary: #f8fafc;
--text-secondary: #94a3b8;
--gradient-map: linear-gradient(135deg, #6366f1 0%, #a855f7 100%);
--gradient-debug: linear-gradient(135deg, #ec4899 0%, #ef4444 100%);
--shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Poppins', sans-serif;
background: var(--bg-primary);
color: var(--text-primary);
line-height: 1.6;
overflow-x: hidden;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.progress-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 5px;
background: var(--bg-secondary);
z-index: 1000;
}
.progress-bar {
height: 100%;
background: var(--gradient-map);
width: 0%;
transition: width 0.3s ease;
}
.hero {
text-align: center;
padding: 100px 20px;
background: var(--gradient-map);
position: relative;
overflow: hidden;
border-radius: 0 0 50px 50px;
}
.hero::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="2" fill="white" opacity="0.1"/></svg>');
animation: float 20s linear infinite;
}
@keyframes float {
from { transform: translateY(0); }
to { transform: translateY(-100px); }
}
.hero-content {
position: relative;
z-index: 1;
}
.map-icon {
font-size: 5rem;
margin-bottom: 20px;
animation: mapZoom 3s ease-in-out infinite;
}
@keyframes mapZoom {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.2); }
}
.command-display {
display: inline-block;
background: rgba(0, 0, 0, 0.4);
padding: 25px 40px;
border-radius: 15px;
font-family: 'Fira Code', monospace;
font-size: 1.1rem;
margin: 30px 0;
border: 3px solid rgba(255, 255, 255, 0.3);
animation: pulse 2s ease-in-out infinite;
color: white;
font-weight: 600;
}
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.05); }
}
.hero h1 {
font-size: 3.5rem;
font-weight: 900;
margin-bottom: 20px;
color: white;
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
}
.hero p {
font-size: 1.4rem;
opacity: 0.95;
color: white;
}
.section {
margin: 60px 0;
}
.section-title {
font-size: 2.5rem;
margin-bottom: 30px;
background: var(--gradient-map);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
display: inline-block;
font-weight: 700;
}
.card {
background: var(--bg-card);
border-radius: 20px;
padding: 40px;
margin: 30px 0;
box-shadow: var(--shadow);
border: 1px solid rgba(255, 255, 255, 0.05);
transition: transform 0.3s ease;
}
.card:hover {
transform: translateY(-5px);
}
.code-block {
background: #1e1e1e;
border-radius: 15px;
padding: 25px;
margin: 20px 0;
font-family: 'Fira Code', monospace;
position: relative;
}
.code-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
padding-bottom: 15px;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.terminal-dots {
display: flex;
gap: 6px;
}
.terminal-dot {
width: 12px;
height: 12px;
border-radius: 50%;
}
.dot-red { background: #ff5f56; }
.dot-yellow { background: #ffbd2e; }
.dot-green { background: #27c93f; }
.copy-btn {
background: var(--accent-purple);
color: white;
border: none;
padding: 8px 16px;
border-radius: 8px;
cursor: pointer;
font-size: 0.9rem;
transition: all 0.3s ease;
}
.copy-btn:hover {
background: var(--accent-blue);
transform: scale(1.05);
}
.copy-btn.copied {
background: var(--accent-green);
}
pre {
margin: 0;
overflow-x: auto;
}
code {
color: #e0e0e0;
font-size: 0.95rem;
line-height: 1.8;
}
.code-comment { color: #6a9955; }
.code-string { color: #ce9178; }
.code-keyword { color: #569cd6; }
.code-node { color: #6366f1; font-weight: 600; }
.code-flag { color: #a855f7; font-weight: 600; }
.code-error { color: #ef4444; }
.steps {
counter-reset: step-counter;
}
.step {
background: var(--bg-secondary);
border-radius: 15px;
padding: 30px;
margin: 20px 0;
position: relative;
padding-left: 100px;
transition: all 0.3s ease;
}
.step:hover {
background: var(--bg-card);
transform: translateX(10px);
}
.step::before {
counter-increment: step-counter;
content: counter(step-counter);
position: absolute;
left: 20px;
top: 50%;
transform: translateY(-50%);
width: 60px;
height: 60px;
background: var(--gradient-map);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.8rem;
font-weight: 900;
color: white;
}
.step h3 {
color: var(--accent-indigo);
margin-bottom: 10px;
font-size: 1.5rem;
}
.feature-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 25px;
margin: 30px 0;
}
.feature-card {
background: var(--bg-secondary);
padding: 30px;
border-radius: 15px;
text-align: center;
transition: all 0.3s ease;
border: 2px solid transparent;
}
.feature-card:hover {
border-color: var(--accent-indigo);
transform: translateY(-10px);
}
.feature-icon {
font-size: 3.5rem;
margin-bottom: 15px;
}
.feature-title {
font-weight: 600;
color: var(--accent-indigo);
margin-bottom: 10px;
font-size: 1.3rem;
}
.demo-container {
background: var(--bg-secondary);
border-radius: 20px;
padding: 40px;
margin: 30px 0;
}
.stack-trace-box {
background: var(--bg-card);
border-radius: 15px;
padding: 30px;
margin: 30px 0;
border: 2px solid var(--accent-indigo);
}
.comparison-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin: 30px 0;
}
.comparison-item {
background: var(--bg-secondary);
padding: 25px;
border-radius: 15px;
border: 2px solid transparent;
}
.comparison-item.without {
border-color: var(--accent-red);
}
.comparison-item.with {
border-color: var(--accent-green);
}
.terminal {
background: #1e1e1e;
border-radius: 15px;
padding: 20px;
font-family: 'Fira Code', monospace;
min-height: 250px;
margin: 20px 0;
overflow-y: auto;
max-height: 500px;
}
.terminal-line {
margin: 10px 0;
}
.terminal-prompt {
color: var(--accent-green);
}
.terminal-success {
color: var(--accent-green);
font-weight: 600;
}
.demo-button {
background: var(--gradient-map);
color: white;
border: none;
padding: 15px 40px;
border-radius: 50px;
font-size: 1.1rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
gap: 10px;
margin: 10px;
}
.demo-button:hover {
transform: scale(1.05);
box-shadow: 0 10px 30px rgba(99, 102, 241, 0.4);
}
.tabs {
display: flex;
gap: 10px;
margin-bottom: 20px;
flex-wrap: wrap;
}
.tab {
padding: 12px 24px;
background: var(--bg-secondary);
border: none;
border-radius: 10px;
color: var(--text-primary);
cursor: pointer;
transition: all 0.3s ease;
font-size: 1rem;
}
.tab:hover {
background: var(--bg-card);
}
.tab.active {
background: var(--gradient-map);
color: white;
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
}
.accordion-header {
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px;
background: var(--bg-secondary);
border-radius: 12px;
margin: 15px 0;
transition: all 0.3s ease;
}
.accordion-header:hover {
background: var(--bg-card);
}
.accordion-icon {
transition: transform 0.3s ease;
font-size: 1.2rem;
}
.accordion-icon.active {
transform: rotate(180deg);
}
.accordion-content {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease;
}
.accordion-content.active {
max-height: 2000px;
}
.accordion-body {
padding: 20px;
background: var(--bg-secondary);
border-radius: 12px;
margin-top: 5px;
}
.tip, .warning, .success, .info {
padding: 20px;
border-radius: 10px;
margin: 20px 0;
}
.tip {
background: rgba(59, 130, 246, 0.1);
border-left: 4px solid var(--accent-blue);
}
.tip::before { content: '💡 '; font-size: 1.5rem; }
.warning {
background: rgba(239, 68, 68, 0.1);
border-left: 4px solid var(--accent-red);
}
.warning::before { content: '⚠️ '; font-size: 1.5rem; }
.success {
background: rgba(16, 185, 129, 0.1);
border-left: 4px solid var(--accent-green);
}
.success::before { content: '✅ '; font-size: 1.5rem; }
.info {
background: rgba(236, 72, 153, 0.1);
border-left: 4px solid var(--accent-pink);
}
.info::before { content: '🔍 '; font-size: 1.5rem; }
.quiz-container {
background: var(--bg-card);
border-radius: 20px;
padding: 40px;
margin: 30px 0;
}
.quiz-question {
margin: 30px 0;
}
.quiz-question h3 {
color: var(--accent-purple);
margin-bottom: 20px;
font-size: 1.3rem;
}
.quiz-options {
display: flex;
flex-direction: column;
gap: 15px;
}
.quiz-option {
background: var(--bg-secondary);
padding: 20px;
border-radius: 12px;
cursor: pointer;
transition: all 0.3s ease;
border: 2px solid transparent;
}
.quiz-option:hover {
border-color: var(--accent-blue);
transform: translateX(10px);
}
.quiz-option.correct {
border-color: var(--accent-green);
background: rgba(16, 185, 129, 0.1);
}
.quiz-option.incorrect {
border-color: var(--accent-red);
background: rgba(239, 68, 68, 0.1);
}
.quiz-feedback {
margin-top: 15px;
padding: 15px;
border-radius: 10px;
display: none;
}
.quiz-feedback.show {
display: block;
}
.quiz-feedback.correct {
background: rgba(16, 185, 129, 0.1);
border-left: 4px solid var(--accent-green);
}
.quiz-feedback.incorrect {
background: rgba(239, 68, 68, 0.1);
border-left: 4px solid var(--accent-red);
}
.cheat-sheet {
background: var(--gradient-map);
border-radius: 20px;
padding: 40px;
margin: 30px 0;
color: white;
}
.cheat-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
margin-top: 30px;
}
.cheat-item {
background: rgba(255, 255, 255, 0.15);
backdrop-filter: blur(10px);
padding: 20px;
border-radius: 15px;
border: 1px solid rgba(255, 255, 255, 0.2);
}
.cheat-item h4 {
color: white;
margin-bottom: 10px;
font-weight: 600;
}
.cheat-item code {
background: rgba(0, 0, 0, 0.3);
padding: 4px 8px;
border-radius: 5px;
font-size: 0.9rem;
color: white;
}
.highlight {
color: var(--accent-yellow);
font-weight: 600;
}
.footer {
text-align: center;
padding: 40px 20px;
background: var(--bg-secondary);
margin-top: 80px;
border-radius: 20px;
}
.footer p {
color: var(--text-secondary);
margin: 10px 0;
}
.badge {
display: inline-block;
padding: 6px 12px;
background: var(--gradient-map);
border-radius: 20px;
font-size: 0.85rem;
font-weight: 600;
margin: 5px;
}
.confetti {
position: fixed;
width: 10px;
height: 10px;
background: var(--accent-indigo);
animation: confetti-fall 3s linear forwards;
z-index: 9999;
}
@keyframes confetti-fall {
to {
transform: translateY(100vh) rotate(360deg);
opacity: 0;
}
}
@media (max-width: 768px) {
.hero h1 { font-size: 2rem; }
.command-display { font-size: 0.85rem; padding: 15px 20px; }
.section-title { font-size: 1.8rem; }
.card { padding: 25px; }
.step { padding-left: 80px; }
.step::before { width: 50px; height: 50px; font-size: 1.5rem; }
.comparison-grid { grid-template-columns: 1fr; }
}
</style>
</head>
<body>
<div class="progress-container">
<div class="progress-bar" id="progressBar"></div>
</div>
<div class="hero">
<div class="hero-content">
<div class="map-icon">🗺️</div>
<h1>Master Source Maps!</h1>
<div class="command-display">node --enable-source-maps app.js</div>
<p>Get readable stack traces for debugging! 🔍</p>
</div>
</div>
<div class="container">
<!-- What Is It -->
<section class="section">
<h2 class="section-title">🤔 What Are Source Maps?</h2>
<div class="card">
<p style="font-size: 1.2rem; margin-bottom: 20px;">
This command runs your Node.js app with <span class="highlight">source map support enabled</span>, which translates error stack traces from compiled/transpiled code back to your <strong>original source code</strong>! 🗺️
</p>
<p style="margin-bottom: 20px;">
Think of it like having a GPS translator! 🧭 When you write TypeScript or modern JavaScript that gets compiled to older JavaScript, errors point to the compiled code (line 2847 of bundle.js). With source maps, Node translates that back to "line 42 of app.ts" - your actual code! It's like having a map that shows you where you really are!
</p>
<div class="info">
<strong>Breaking It Down:</strong>
<ul style="margin-left: 30px; margin-top: 10px; line-height: 2;">
<li><code class="code-node">node</code> - Node.js runtime</li>
<li><code class="code-flag">--enable-source-maps</code> - Enable source map support</li>
<li><code>app.js</code> - Your application file</li>
<li>Reads .map files to translate stack traces</li>
<li>Shows original source locations in errors</li>
</ul>
</div>
<div style="margin-top: 30px;">
<h3 style="color: var(--accent-pink); margin-bottom: 15px;">What's a Source Map? 🔍</h3>
<p>A source map is a JSON file (like <code>app.js.map</code>) that maps compiled code back to original source. When TypeScript compiles <code>app.ts</code> to <code>app.js</code>, it creates <code>app.js.map</code> showing the connection between them!</p>
</div>
</div>
</section>
<!-- Stack Trace Comparison -->
<section class="section">
<h2 class="section-title">📊 Before & After</h2>
<div class="card">
<h3 style="margin-bottom: 20px; text-align: center;">See The Difference! 🎯</h3>
<div class="comparison-grid">
<div class="comparison-item without">
<h4 style="color: var(--accent-red); margin-bottom: 15px;">❌ Without Source Maps</h4>
<div class="code-block" style="margin-top: 15px;">
<pre><code><span class="code-error">Error: Something broke!</span>
at Object.<anonymous> (dist/app.js:2847:15)
at Module._compile (internal/modules:73:30)
at Object.Module._extensions (internal/modules:84:10)</code></pre>
</div>
<p style="margin-top: 10px; font-size: 0.9rem; color: var(--text-secondary);">😵 Line 2847 of compiled code? Good luck finding that!</p>
</div>
<div class="comparison-item with">
<h4 style="color: var(--accent-green); margin-bottom: 15px;">✅ With Source Maps</h4>
<div class="code-block" style="margin-top: 15px;">
<pre><code><span class="code-error">Error: Something broke!</span>
at greetUser (src/app.ts:42:15)
at main (src/app.ts:58:5)
at Object.<anonymous> (src/app.ts:65:1)</code></pre>
</div>
<p style="margin-top: 10px; font-size: 0.9rem; color: var(--text-secondary);">😊 Line 42 of app.ts! Now you know exactly where to look!</p>
</div>
</div>
</div>
</section>
<!-- Why Use It -->
<section class="section">
<h2 class="section-title">✨ Why Enable Source Maps?</h2>
<div class="card">
<div class="feature-grid">
<div class="feature-card">
<div class="feature-icon">🐛</div>
<div class="feature-title">Better Debugging</div>
<p style="color: var(--text-secondary);">Find bugs faster!</p>
</div>
<div class="feature-card">
<div class="feature-icon">📍</div>
<div class="feature-title">Accurate Locations</div>
<p style="color: var(--text-secondary);">See original line numbers!</p>
</div>
<div class="feature-card">
<div class="feature-icon">📝</div>
<div class="feature-title">TypeScript Support</div>
<p style="color: var(--text-secondary);">Debug .ts files easily!</p>
</div>
<div class="feature-card">
<div class="feature-icon">⚡</div>
<div class="feature-title">Faster Fixes</div>
<p style="color: var(--text-secondary);">No guessing games!</p>
</div>
<div class="feature-card">
<div class="feature-icon">🎯</div>
<div class="feature-title">Production Debugging</div>
<p style="color: var(--text-secondary);">Debug minified code!</p>
</div>
<div class="feature-card">
<div class="feature-icon">🔍</div>
<div class="feature-title">Better Logs</div>
<p style="color: var(--text-secondary);">Readable stack traces!</p>
</div>
</div>
</div>
</section>
<!-- How It Works -->
<section class="section">
<h2 class="section-title">⚙️ How Does It Work?</h2>
<div class="card">
<div class="steps">
<div class="step">
<h3>Step 1: Compilation</h3>
<p>TypeScript/Babel compiles your code and generates .map files.</p>
</div>
<div class="step">
<h3>Step 2: Node Starts</h3>
<p>Run with --enable-source-maps flag.</p>
</div>
<div class="step">
<h3>Step 3: Error Occurs</h3>
<p>An error happens in your running app.</p>
</div>
<div class="step">
<h3>Step 4: Stack Trace Generated</h3>
<p>Node creates a stack trace pointing to compiled code.</p>
</div>
<div class="step">
<h3>Step 5: Source Map Lookup</h3>
<p>Node reads the .map file to find original locations.</p>
</div>
<div class="step">
<h3>Step 6: Translated Output</h3>
<p>You see errors pointing to your original source! 🎉</p>
</div>
</div>
</div>
</section>
<!-- Live Demo -->
<section class="section">
<h2 class="section-title">🎮 Interactive Demo</h2>
<div class="demo-container">
<div style="margin-bottom: 30px; text-align: center;">
<h4 style="margin-bottom: 15px;">See Stack Traces Transform! 🔍</h4>
<button class="demo-button" onclick="simulateWithoutMaps()">
<span>❌</span>
<span>Without Source Maps</span>
</button>
<button class="demo-button" onclick="simulateWithMaps()">
<span>✅</span>
<span>With Source Maps</span>
</button>
<button class="demo-button" onclick="simulateComparison()">
<span>⚖️</span>
<span>Side-by-Side</span>
</button>
</div>
<div class="terminal" id="terminal">
<div class="terminal-line">
<span class="terminal-prompt">$</span>
<span style="color: var(--text-secondary);"> Ready to run Node.js...</span>
</div>
</div>
</div>
</section>
<!-- Code Breakdown -->
<section class="section">
<h2 class="section-title">💻 Usage Examples</h2>
<div class="card">
<div class="tabs">
<button class="tab active" onclick="switchTab('basic')">Basic Usage</button>
<button class="tab" onclick="switchTab('typescript')">TypeScript</button>
<button class="tab" onclick="switchTab('package')">package.json</button>
<button class="tab" onclick="switchTab('alternatives')">Alternatives</button>
</div>
<div id="basic" class="tab-content active">
<h3 style="color: var(--accent-pink); margin-bottom: 15px;">Basic Usage</h3>
<div class="code-block">
<div class="code-header">
<div class="terminal-dots">
<div class="terminal-dot dot-red"></div>
<div class="terminal-dot dot-yellow"></div>
<div class="terminal-dot dot-green"></div>
</div>
<button class="copy-btn" onclick="copyCode('basic-code')">📋 Copy</button>
</div>
<pre><code id="basic-code"><span class="code-comment"># Run with source map support</span>
node --enable-source-maps app.js
<span class="code-comment"># Works with any Node.js app that has .map files</span>
node --enable-source-maps dist/server.js
<span class="code-comment"># Combine with other flags</span>
node --enable-source-maps --inspect app.js</code></pre>
</div>
<div class="success" style="margin-top: 15px;">
<strong>Result:</strong> Stack traces now show original source locations!
</div>
</div>
<div id="typescript" class="tab-content">
<h3 style="color: var(--accent-pink); margin-bottom: 15px;">TypeScript Setup</h3>
<div class="code-block">
<div class="code-header">
<div class="terminal-dots">
<div class="terminal-dot dot-red"></div>
<div class="terminal-dot dot-yellow"></div>
<div class="terminal-dot dot-green"></div>
</div>
<button class="copy-btn" onclick="copyCode('typescript-code')">📋 Copy</button>
</div>
<pre><code id="typescript-code"><span class="code-comment">// tsconfig.json - Enable source maps</span>
{
<span class="code-string">"compilerOptions"</span>: {
<span class="code-string">"sourceMap"</span>: <span class="code-keyword">true</span>, <span class="code-comment">// Generate .map files</span>
<span class="code-string">"outDir"</span>: <span class="code-string">"./dist"</span>,
<span class="code-string">"rootDir"</span>: <span class="code-string">"./src"</span>
}
}
<span class="code-comment"># Compile TypeScript</span>
tsc
<span class="code-comment"># Run with source maps</span>
node --enable-source-maps dist/app.js
<span class="code-comment"># Now errors show src/app.ts:42 instead of dist/app.js:2847!</span></code></pre>
</div>
<div class="tip" style="margin-top: 15px;">
<strong>Pro Tip:</strong> Always enable sourceMap in tsconfig.json for better debugging!
</div>
</div>
<div id="package" class="tab-content">
<h3 style="color: var(--accent-pink); margin-bottom: 15px;">Add to package.json</h3>
<div class="code-block">
<div class="code-header">
<div class="terminal-dots">
<div class="terminal-dot dot-red"></div>
<div class="terminal-dot dot-yellow"></div>
<div class="terminal-dot dot-green"></div>
</div>
<button class="copy-btn" onclick="copyCode('package-code')">📋 Copy</button>
</div>
<pre><code id="package-code"><span class="code-comment">// package.json</span>
{
<span class="code-string">"name"</span>: <span class="code-string">"my-app"</span>,
<span class="code-string">"scripts"</span>: {
<span class="code-string">"build"</span>: <span class="code-string">"tsc"</span>,
<span class="code-string">"start"</span>: <span class="code-string">"node --enable-source-maps dist/app.js"</span>,
<span class="code-string">"dev"</span>: <span class="code-string">"nodemon --enable-source-maps dist/app.js"</span>,
<span class="code-string">"debug"</span>: <span class="code-string">"node --enable-source-maps --inspect dist/app.js"</span>
}
}
<span class="code-comment"># Now just run:</span>
npm start <span class="code-comment"># With source maps!</span>
npm run dev <span class="code-comment"># Dev mode with source maps!</span></code></pre>
</div>
<div class="success" style="margin-top: 15px;">
<strong>Best Practice:</strong> Add --enable-source-maps to all your npm scripts!
</div>
</div>
<div id="alternatives" class="tab-content">
<h3 style="color: var(--accent-pink); margin-bottom: 15px;">Alternative Methods</h3>
<div class="code-block">
<div class="code-header">
<div class="terminal-dots">
<div class="terminal-dot dot-red"></div>
<div class="terminal-dot dot-yellow"></div>
<div class="terminal-dot dot-green"></div>
</div>
<button class="copy-btn" onclick="copyCode('alternatives-code')">📋 Copy</button>
</div>
<pre><code id="alternatives-code"><span class="code-comment">// Method 1: Command line flag (recommended for Node 12.12+)</span>
node --enable-source-maps app.js
<span class="code-comment">// Method 2: NODE_OPTIONS environment variable</span>
NODE_OPTIONS=<span class="code-string">'--enable-source-maps'</span> node app.js
<span class="code-comment">// Method 3: source-map-support package (older Node versions)</span>
npm install source-map-support
<span class="code-comment">// In your code:</span>
<span class="code-keyword">require</span>(<span class="code-string">'source-map-support'</span>).install();
<span class="code-comment">// Method 4: Using -r flag</span>
node -r source-map-support/register app.js
<span class="code-comment">// Method 5: ts-node (for TypeScript)</span>
ts-node app.ts <span class="code-comment">// Automatically handles source maps</span></code></pre>
</div>
</div>
</div>
</section>
<!-- Common Mistakes -->
<section class="section">
<h2 class="section-title">❌ Common Mistakes</h2>
<div class="card">
<div class="accordion">
<div class="accordion-item">
<div class="accordion-header" onclick="toggleAccordion(this)">
<span><strong>1. Missing .map Files</strong></span>
<span class="accordion-icon">▼</span>
</div>
<div class="accordion-content">
<div class="accordion-body">
<div class="warning">
<strong>Problem:</strong> Source maps don't work because .map files weren't generated
</div>
<div class="success" style="margin-top: 15px;">
<strong>Solution:</strong> Enable sourceMap in tsconfig.json or your build tool config!
</div>
</div>
</div>
</div>
<div class="accordion-item">
<div class="accordion-header" onclick="toggleAccordion(this)">
<span><strong>2. Wrong Node Version</strong></span>
<span class="accordion-icon">▼</span>
</div>
<div class="accordion-content">
<div class="accordion-body">
<div class="warning">
<strong>Problem:</strong> --enable-source-maps not recognized
</div>
<div class="success" style="margin-top: 15px;">
<strong>Solution:</strong> Upgrade to Node.js 12.12.0 or higher! Or use source-map-support package.
</div>
</div>
</div>
</div>
<div class="accordion-item">
<div class="accordion-header" onclick="toggleAccordion(this)">
<span><strong>3. .map Files Not Deployed</strong></span>
<span class="accordion-icon">▼</span>
</div>
<div class="accordion-content">
<div class="accordion-body">
<div class="warning">
<strong>Problem:</strong> Source maps work locally but not in production
</div>
<div class="success" style="margin-top: 15px;">
<strong>Solution:</strong> Ensure .map files are deployed with your app! Don't .gitignore them.
</div>
</div>
</div>
</div>
<div class="accordion-item">
<div class="accordion-header" onclick="toggleAccordion(this)">
<span><strong>4. Inline Source Maps</strong></span>
<span class="accordion-icon">▼</span>
</div>
<div class="accordion-content">
<div class="accordion-body">
<div class="warning">
<strong>Problem:</strong> Using inline source maps in production (increases file size)
</div>
<div class="success" style="margin-top: 15px;">
<strong>Solution:</strong> Use external .map files for production! Set "inlineSourceMap": false
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Pro Tips -->
<section class="section">
<h2 class="section-title">🚀 Pro Tips</h2>
<div class="card">
<div class="tip">
<strong>Always enable in dev</strong> - Add --enable-source-maps to all development scripts!
</div>
<div class="tip">
<strong>TypeScript config</strong> - Set "sourceMap": true in tsconfig.json!
</div>
<div class="tip">
<strong>Production debugging</strong> - Keep .map files for production debugging, just don't serve them publicly!
</div>
<div class="tip">
<strong>Combine with --inspect</strong> - Use both flags for ultimate debugging: <code>--enable-source-maps --inspect</code>
</div>
<div class="tip">
<strong>NODE_OPTIONS</strong> - Set globally: <code>export NODE_OPTIONS='--enable-source-maps'</code>
</div>
<div class="tip">
<strong>Webpack/Babel</strong> - Configure your bundler to generate source maps too!
</div>
<div class="tip">
<strong>Security</strong> - Don't expose .map files publicly in production (use .htaccess or nginx rules)!
</div>
</div>
</section>
<!-- Quiz -->
<section class="section">
<h2 class="section-title">🎯 Knowledge Check Quiz</h2>
<div class="quiz-container">
<p style="margin-bottom: 30px; font-size: 1.1rem;">Test your understanding! 🧠</p>
<div class="quiz-question">
<h3>Question 1: What do source maps do?</h3>
<div class="quiz-options">
<div class="quiz-option" onclick="checkAnswer(this, false, 1)">A) Make your code run faster</div>
<div class="quiz-option" onclick="checkAnswer(this, true, 1)">B) Translate stack traces to original source</div>
<div class="quiz-option" onclick="checkAnswer(this, false, 1)">C) Compress your JavaScript files</div>
</div>
<div class="quiz-feedback" id="feedback1"></div>
</div>
<div class="quiz-question">
<h3>Question 2: What file extension do source maps use?</h3>
<div class="quiz-options">
<div class="quiz-option" onclick="checkAnswer(this, false, 2)">A) .source</div>
<div class="quiz-option" onclick="checkAnswer(this, true, 2)">B) .map</div>
<div class="quiz-option" onclick="checkAnswer(this, false, 2)">C) .trace</div>
</div>
<div class="quiz-feedback" id="feedback2"></div>
</div>
<div class="quiz-question">
<h3>Question 3: Minimum Node.js version for --enable-source-maps?</h3>
<div class="quiz-options">
<div class="quiz-option" onclick="checkAnswer(this, false, 3)">A) Node.js 10.0.0</div>
<div class="quiz-option" onclick="checkAnswer(this, true, 3)">B) Node.js 12.12.0</div>
<div class="quiz-option" onclick="checkAnswer(this, false, 3)">C) Node.js 14.0.0</div>
</div>
<div class="quiz-feedback" id="feedback3"></div>
</div>
<div id="quizScore" style="margin-top: 30px; padding: 20px; background: var(--bg-secondary); border-radius: 12px; display: none;">
<h3 style="color: var(--accent-green); font-size: 1.5rem;">🎉 Quiz Complete!</h3>
<p id="scoreText" style="font-size: 1.2rem; margin-top: 10px;"></p>
</div>
</div>
</section>
<!-- Summary Card -->
<section class="section">
<h2 class="section-title">📚 Quick Reference</h2>
<div class="cheat-sheet">
<h3 style="margin-bottom: 20px; font-size: 2rem;">Source Maps Cheat Sheet! 🔖</h3>
<div class="cheat-grid">
<div class="cheat-item">
<h4>🗺️ Command</h4>
<p><code>node --enable-source-maps app.js</code></p>
<p style="font-size: 0.85rem; margin-top: 5px;">Enable source maps</p>
</div>
<div class="cheat-item">
<h4>📝 TypeScript</h4>
<p><code>"sourceMap": true</code></p>
<p style="font-size: 0.85rem; margin-top: 5px;">In tsconfig.json</p>
</div>
<div class="cheat-item">
<h4>📦 package.json</h4>
<p><code>"start": "node --enable-source-maps dist/app.js"</code></p>
<p style="font-size: 0.85rem; margin-top: 5px;">Add to scripts</p>
</div>
<div class="cheat-item">
<h4>🔍 File Extension</h4>
<p><code>app.js.map</code></p>
<p style="font-size: 0.85rem; margin-top: 5px;">Source map file</p>
</div>
<div class="cheat-item">
<h4>⚙️ NODE_OPTIONS</h4>
<p><code>NODE_OPTIONS='--enable-source-maps'</code></p>
<p style="font-size: 0.85rem; margin-top: 5px;">Global setting</p>
</div>
<div class="cheat-item">
<h4>🎯 Purpose</h4>
<p>Better debugging</p>
<p style="font-size: 0.85rem; margin-top: 5px;">Readable stack traces</p>
</div>
<div class="cheat-item">
<h4>✅ Node Version</h4>
<p>12.12.0+</p>
<p style="font-size: 0.85rem; margin-top: 5px;">Minimum required</p>
</div>
<div class="cheat-item">
<h4>💡 Benefit</h4>
<p>Original locations</p>
<p style="font-size: 0.85rem; margin-top: 5px;">Not compiled code</p>
</div>
</div>
</div>
</section>
<!-- Footer -->
<div class="footer">
<h2 style="font-size: 2rem; margin-bottom: 20px; color: var(--accent-pink);">🎉 Congratulations!</h2>
<p style="font-size: 1.2rem; margin-bottom: 20px;">You now understand <strong>source maps</strong>! 🚀</p>
<div style="margin: 30px 0;">
<span class="badge">🗺️ Map Master</span>
<span class="badge">🐛 Debug Pro</span>
<span class="badge">🚀 Node Expert</span>
</div>
<p style="color: var(--text-secondary); margin-top: 30px;">Generated by <strong>AI Prompt Dictionary</strong> 🤖</p>
<p style="color: var(--text-secondary); font-size: 0.9rem;">Made with ❤️ for developers learning Node.js</p>
</div>
</div>
<script>
// Progress bar
window.addEventListener('scroll', () => {
const winScroll = document.body.scrollTop || document.documentElement.scrollTop;
const height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
const scrolled = (winScroll / height) * 100;
document.getElementById('progressBar').style.width = scrolled + '%';
});
// Copy to clipboard
function copyCode(codeId) {
const code = document.getElementById(codeId).innerText;
navigator.clipboard.writeText(code).then(() => {
event.target.textContent = '✅ Copied!';
event.target.classList.add('copied');
setTimeout(() => {
event.target.textContent = '📋 Copy';
event.target.classList.remove('copied');
}, 2000);
});
}
// Tab switching
function switchTab(tabName) {
document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
document.getElementById(tabName).classList.add('active');
event.target.classList.add('active');
}
// Accordion toggle
function toggleAccordion(header) {
const content = header.nextElementSibling;
const icon = header.querySelector('.accordion-icon');
content.classList.toggle('active');
icon.classList.toggle('active');
}
// Simulate without source maps
function simulateWithoutMaps() {
const terminal = document.getElementById('terminal');
terminal.innerHTML = '<div class="terminal-line"><span class="terminal-prompt">$</span> node dist/app.js</div>';
setTimeout(() => {
terminal.innerHTML += '<div style="color: var(--accent-cyan); margin-top: 10px;">🚀 Starting application...</div>';
}, 500);
setTimeout(() => {
terminal.innerHTML += '<div style="color: var(--accent-red); margin-top: 15px; font-weight: 600;">❌ Error: Cannot read property \'name\' of undefined</div>';
terminal.innerHTML += '<div style="color: var(--text-secondary); margin-left: 20px; margin-top: 5px;">at Object.<anonymous> (dist/app.js:2847:15)</div>';
terminal.innerHTML += '<div style="color: var(--text-secondary); margin-left: 20px;">at Module._compile (internal/modules/cjs/loader.js:1063:30)</div>';
terminal.innerHTML += '<div style="color: var(--text-secondary); margin-left: 20px;">at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)</div>';
terminal.innerHTML += '<div style="color: var(--accent-yellow); margin-top: 15px;">😵 Line 2847 of compiled code... where is that in my source?!</div>';
}, 1500);
}
// Simulate with source maps
function simulateWithMaps() {
const terminal = document.getElementById('terminal');
terminal.innerHTML = '<div class="terminal-line"><span class="terminal-prompt">$</span> node --enable-source-maps dist/app.js</div>';
setTimeout(() => {
terminal.innerHTML += '<div style="color: var(--accent-cyan); margin-top: 10px;">🚀 Starting application with source maps...</div>';
terminal.innerHTML += '<div style="color: var(--accent-indigo); margin-top: 5px;">🗺️ Source map support enabled!</div>';
}, 500);
setTimeout(() => {
terminal.innerHTML += '<div style="color: var(--accent-red); margin-top: 15px; font-weight: 600;">❌ Error: Cannot read property \'name\' of undefined</div>';
terminal.innerHTML += '<div style="color: var(--accent-green); margin-left: 20px; margin-top: 5px; font-weight: 600;">at greetUser (src/app.ts:42:15)</div>';
terminal.innerHTML += '<div style="color: var(--accent-green); margin-left: 20px; font-weight: 600;">at main (src/app.ts:58:5)</div>';
terminal.innerHTML += '<div style="color: var(--accent-green); margin-left: 20px; font-weight: 600;">at Object.<anonymous> (src/app.ts:65:1)</div>';
terminal.innerHTML += '<div style="color: var(--accent-green); margin-top: 15px;">😊 Perfect! Line 42 of app.ts - I know exactly where to look!</div>';
createConfetti();
}, 1500);
}
// Simulate comparison
function simulateComparison() {
const terminal = document.getElementById('terminal');
terminal.innerHTML = '<div style="color: var(--accent-purple); font-weight: 600; font-size: 1.1rem;">📊 Stack Trace Comparison</div>';
terminal.innerHTML += '<div style="margin-top: 20px; color: var(--accent-red);">❌ WITHOUT SOURCE MAPS:</div>';
terminal.innerHTML += '<div style="margin-left: 20px; color: var(--text-secondary); font-size: 0.9rem;">at Object.<anonymous> (dist/app.js:2847:15)</div>';
terminal.innerHTML += '<div style="margin-left: 20px; color: var(--text-secondary); font-size: 0.85rem;">😵 Compiled code location - hard to debug!</div>';
terminal.innerHTML += '<div style="margin-top: 20px; color: var(--accent-green);">✅ WITH SOURCE MAPS:</div>';
terminal.innerHTML += '<div style="margin-left: 20px; color: var(--text-secondary); font-size: 0.9rem;">at greetUser (src/app.ts:42:15)</div>';
terminal.innerHTML += '<div style="margin-left: 20px; color: var(--text-secondary); font-size: 0.85rem;">😊 Original source location - easy to find!</div>';
terminal.innerHTML += '<div style="margin-top: 20px; color: var(--accent-cyan); font-weight: 600;">💡 Source maps translate compiled → original!</div>';
createConfetti();
}
// Quiz system
let quizScore = 0;
let questionsAnswered = 0;
function checkAnswer(element, isCorrect, questionNum) {
const options = element.parentElement.querySelectorAll('.quiz-option');
options.forEach(opt => opt.style.pointerEvents = 'none');
const feedback = document.getElementById('feedback' + questionNum);
if (isCorrect) {
element.classList.add('correct');
feedback.className = 'quiz-feedback correct show';
feedback.innerHTML = '<strong>🎉 Correct!</strong> Great job!';
quizScore++;
createConfetti();
} else {
element.classList.add('incorrect');
feedback.className = 'quiz-feedback incorrect show';
feedback.innerHTML = '<strong>❌ Not quite!</strong> Review the material and try again!';
}
questionsAnswered++;
if (questionsAnswered === 3) {
setTimeout(() => {
document.getElementById('quizScore').style.display = 'block';
document.getElementById('scoreText').textContent = `You scored ${quizScore}/3! ${quizScore === 3 ? '🏆 Perfect!' : quizScore === 2 ? '👍 Good job!' : '💪 Keep learning!'}`;
}, 1000);
}
}
// Confetti animation
function createConfetti() {
const colors = ['#6366f1', '#a855f7', '#ec4899', '#3b82f6', '#10b981'];
for (let i = 0; i < 50; i++) {
const confetti = document.createElement('div');
confetti.className = 'confetti';
confetti.style.left = Math.random() * window.innerWidth + 'px';
confetti.style.background = colors[Math.floor(Math.random() * colors.length)];
confetti.style.animationDuration = (2 + Math.random() * 2) + 's';
document.body.appendChild(confetti);
setTimeout(() => confetti.remove(), 4000);
}
}
</script>
</body>
</html>
Live Preview