Generates and consumes source maps for debugging tools that map minified code back to original source code
—
The SourceMapGenerator class provides functionality for creating source maps incrementally during code generation. This is ideal for build tools, transpilers, and bundlers that need to track the relationship between generated code and original source files.
Creates source maps incrementally by adding mappings one at a time.
/**
* Creates a new source map generator
* @param args - Configuration options for the source map
*/
class SourceMapGenerator {
constructor(args?: StartOfSourceMap);
/**
* Creates a new SourceMapGenerator based on a SourceMapConsumer
* @param sourceMapConsumer - The source map to convert
*/
static fromSourceMap(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator;
/**
* Add a single mapping from original source line and column to the generated
* source's line and column for this source map being created
* @param mapping - The mapping object containing position information
*/
addMapping(mapping: Mapping): void;
/**
* Set the source content for a source file
* @param sourceFile - The filename of the original source
* @param sourceContent - The content of the original source file
*/
setSourceContent(sourceFile: string, sourceContent: string): void;
/**
* Applies the mappings of a sub-source-map for a specific source file to the
* source map being generated. Each mapping to the supplied source file is
* rewritten using the supplied source map.
* @param sourceMapConsumer - The source map to be applied
* @param sourceFile - Optional filename of the source file
* @param sourceMapPath - Optional dirname of the path to the source map
*/
applySourceMap(
sourceMapConsumer: SourceMapConsumer,
sourceFile?: string,
sourceMapPath?: string
): void;
/**
* Render the source map as a JSON string
*/
toString(): string;
/**
* Export the source map as a raw object
*/
toJSON(): RawSourceMap;
}
interface StartOfSourceMap {
/** The filename of the generated source */
file?: string;
/** A root for all relative URLs in this source map */
sourceRoot?: string;
/** Skip validation of mappings */
skipValidation?: boolean;
}
interface Mapping {
/** An object with the generated line and column positions */
generated: Position;
/** An object with the original line and column positions */
original: Position;
/** The original source file (relative to the sourceRoot) */
source: string;
/** An optional original token name for this mapping */
name?: string;
}
interface Position {
line: number; // 1-based line number
column: number; // 0-based column number
}
interface RawSourceMap {
version: number;
sources: string[];
names: string[];
sourceRoot?: string;
sourcesContent?: string[];
mappings: string;
file: string;
}Usage Examples:
import { SourceMapGenerator } from "source-map";
// Create a new source map
const map = new SourceMapGenerator({
file: "bundled.js",
sourceRoot: "http://example.com/"
});
// Add mappings during code generation
map.addMapping({
generated: { line: 1, column: 0 },
source: "input.js",
original: { line: 1, column: 0 }
});
map.addMapping({
generated: { line: 1, column: 18 },
source: "input.js",
original: { line: 1, column: 11 },
name: "add"
});
// Set source content
map.setSourceContent("input.js", "function add(a,b){return a+b}");
// Generate the source map
const sourceMapJSON = map.toString();
console.log(sourceMapJSON);The SourceMapGenerator constructor accepts an optional configuration object:
interface StartOfSourceMap {
/** The filename of the generated source */
file?: string;
/** A root for all relative URLs in this source map */
sourceRoot?: string;
/** Skip validation of mappings */
skipValidation?: boolean;
}Usage:
const generator = new SourceMapGenerator({
file: "output.js", // Generated file name
sourceRoot: "/project/src/", // Base path for source files
skipValidation: false // Enable mapping validation (default)
});Add individual mappings between generated and original positions:
/**
* Add a single mapping from original source line and column to the generated
* source's line and column for this source map being created
*/
addMapping(mapping: Mapping): void;
interface Mapping {
generated: Position; // Required: position in generated code
original: Position; // Required: position in original code
source: string; // Required: original source file name
name?: string; // Optional: original identifier name
}Usage:
// Basic mapping
map.addMapping({
generated: { line: 10, column: 5 },
original: { line: 20, column: 15 },
source: "original.js"
});
// Mapping with identifier name
map.addMapping({
generated: { line: 15, column: 8 },
original: { line: 25, column: 12 },
source: "original.js",
name: "functionName"
});Set the content of original source files:
/**
* Set the source content for a source file
* @param sourceFile - The filename of the original source
* @param sourceContent - The content of the original source file
*/
setSourceContent(sourceFile: string, sourceContent: string): void;Usage:
// Set content for debugging
map.setSourceContent("math.js", `
function add(a, b) {
return a + b;
}
`);
map.setSourceContent("utils.js", `
export function format(value) {
return String(value);
}
`);Combine multiple source maps when dealing with transpilation chains:
/**
* Applies the mappings of a sub-source-map for a specific source file
* @param sourceMapConsumer - The source map to be applied
* @param sourceFile - Optional filename of the source file
* @param sourceMapPath - Optional dirname of the path to the source map
*/
applySourceMap(
sourceMapConsumer: SourceMapConsumer,
sourceFile?: string,
sourceMapPath?: string
): void;Usage:
import { SourceMapConsumer, SourceMapGenerator } from "source-map";
// Apply TypeScript -> JavaScript source map to JavaScript -> minified map
const tsToJsMap = await new SourceMapConsumer(typescriptSourceMap);
const jsToMinMap = new SourceMapGenerator({ file: "output.min.js" });
// This creates a direct TypeScript -> minified mapping
jsToMinMap.applySourceMap(tsToJsMap, "intermediate.js");Convert a SourceMapConsumer back into a generator:
/**
* Creates a new SourceMapGenerator based on a SourceMapConsumer
* @param sourceMapConsumer - The source map to convert
*/
static fromSourceMap(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator;Usage:
// Load existing source map
const consumer = await new SourceMapConsumer(existingSourceMap);
// Convert to generator for modification
const generator = SourceMapGenerator.fromSourceMap(consumer);
// Add additional mappings
generator.addMapping({
generated: { line: 100, column: 0 },
original: { line: 50, column: 10 },
source: "new-file.js"
});
// Clean up consumer
consumer.destroy();Export the source map in various formats:
/**
* Render the source map as a JSON string
*/
toString(): string;
/**
* Export the source map as a raw object
*/
toJSON(): RawSourceMap;Usage:
// Get as JSON string for embedding
const jsonString = generator.toString();
console.log(jsonString);
// Output: {"version":3,"sources":["input.js"],"names":[],"mappings":"AAAA","file":"output.js"}
// Get as object for manipulation
const mapObject = generator.toJSON();
console.log(mapObject.sources); // ["input.js"]
console.log(mapObject.version); // 3The SourceMapGenerator validates mappings and throws errors for invalid inputs:
Example error handling:
try {
map.addMapping({
generated: { line: 0, column: 5 }, // Invalid: line must be >= 1
original: { line: 1, column: 0 },
source: "test.js"
});
} catch (error) {
console.error("Invalid mapping:", error.message);
}Install with Tessl CLI
npx tessl i tessl/npm-source-map