Source code handling classes for webpack and other build tools with optional source map support
—
Classes for combining, modifying, and transforming sources while preserving source map information.
Concatenates multiple sources or strings into a single source, preserving source map information from all components.
/**
* Concatenates multiple sources or strings
* @param items - Sources, strings, or source-like objects to concatenate
*/
class ConcatSource extends Source {
constructor(...items: ConcatSourceChild[]);
/** Adds an item to the end of the concatenated source */
add(item: ConcatSourceChild): void;
/** Adds multiple items efficiently without optimization checks */
addAllSkipOptimizing(items: ConcatSourceChild[]): void;
/** Returns array of child sources */
getChildren(): Source[];
/** Streams chunks from all concatenated sources */
streamChunks(
options: StreamChunksOptions,
onChunk: OnChunk,
onSource: OnSource,
onName: OnName
): GeneratedSourceInfo;
}
/** Items that can be concatenated */
type ConcatSourceChild = string | Source | SourceLike;Usage Examples:
const { ConcatSource, RawSource, OriginalSource } = require("webpack-sources");
// Concatenate mixed content
const concat = new ConcatSource(
"// Header comment\n",
new OriginalSource("const x = 1;", "module.js"),
"\n",
new RawSource("console.log(x);")
);
console.log(concat.source());
// Output:
// // Header comment
// const x = 1;
// console.log(x);
// Add more content dynamically
concat.add("\n// Footer");
concat.add(new RawSource("module.exports = x;"));
// Check children
const children = concat.getChildren();
console.log(children.length); // Number of child sources
// Efficient bulk addition
const moreItems = [
"\n// More code",
new RawSource("console.log('done');")
];
concat.addAllSkipOptimizing(moreItems);Decorates a source with replacements and insertions, preserving source map information with identity mappings support.
/**
* Source with replacements and insertions
* @param source - The source to decorate with replacements
* @param name - Optional name for the source
*/
class ReplaceSource extends Source {
constructor(source: Source, name?: string);
/**
* Replaces characters from start to end with replacement text
* @param start - Start position (0-indexed, inclusive)
* @param end - End position (0-indexed, inclusive)
* @param newValue - Replacement text
* @param name - Optional name for the replacement
*/
replace(start: number, end: number, newValue: string, name?: string): void;
/**
* Inserts text before the specified position
* @param pos - Position to insert before (0-indexed)
* @param newValue - Text to insert
* @param name - Optional name for the insertion
*/
insert(pos: number, newValue: string, name?: string): void;
/** Returns the original decorated source */
original(): Source;
/** Returns the name if provided */
getName(): string | undefined;
/** Returns array of all replacements */
getReplacements(): Replacement[];
/** Streams chunks with replacement and insertion processing */
streamChunks(
options: StreamChunksOptions,
onChunk: OnChunk,
onSource: OnSource,
onName: OnName
): GeneratedSourceInfo;
/** Replacement class constructor */
static Replacement: typeof Replacement;
}Usage Examples:
const { ReplaceSource, OriginalSource } = require("webpack-sources");
const original = new OriginalSource(
"function hello(name) {\n console.log('Hello ' + name);\n}",
"hello.js"
);
const modified = new ReplaceSource(original, "modified-hello.js");
// Replace function name
modified.replace(9, 13, "greet"); // Replace "hello" with "greet"
// Insert parameter validation
modified.insert(23, "if (!name) return; ");
// Replace string concatenation with template literal
modified.replace(45, 63, "`Hello ${name}`");
console.log(modified.source());
// Output:
// function greet(name) {
// if (!name) return; console.log(`Hello ${name}`);
// }
console.log(modified.getName()); // "modified-hello.js"
console.log(modified.original() === original); // true
// Get all modifications
const replacements = modified.getReplacements();
console.log(replacements.length); // Number of replacements/insertionsPrefixes every line of a source with a provided string, useful for indentation or commenting.
/**
* Prefixes every line with a string
* @param prefix - String to prefix each line with
* @param source - Source to prefix (string, Buffer, or Source)
*/
class PrefixSource extends Source {
constructor(prefix: string, source: string | Source | Buffer);
/** Returns the prefix string */
getPrefix(): string;
/** Returns the original source */
original(): Source;
/** Streams chunks with line prefixing */
streamChunks(
options: StreamChunksOptions,
onChunk: OnChunk,
onSource: OnSource,
onName: OnName
): GeneratedSourceInfo;
}Usage Examples:
const { PrefixSource, RawSource } = require("webpack-sources");
// Add indentation
const code = "console.log('test');\nconsole.log('done');";
const indented = new PrefixSource(" ", code);
console.log(indented.source());
// Output:
// console.log('test');
// console.log('done');
// Add comment prefix
const commented = new PrefixSource("// ", new RawSource(code));
console.log(commented.source());
// Output:
// // console.log('test');
// // console.log('done');
console.log(commented.getPrefix()); // "// "
console.log(commented.original().source()); // Original uncommented code
// Complex prefixing
const numbered = new PrefixSource("/* Line */ ", code);
console.log(numbered.source());
// Output:
// /* Line */ console.log('test');
// /* Line */ console.log('done');Represents a single replacement operation in ReplaceSource.
/**
* Represents a replacement operation
* @param start - Start position (0-indexed, inclusive)
* @param end - End position (0-indexed, inclusive)
* @param content - Replacement content
* @param name - Optional name for the replacement
*/
class Replacement {
constructor(start: number, end: number, content: string, name?: string);
/** Start position of replacement */
start: number;
/** End position of replacement */
end: number;
/** Replacement content */
content: string;
/** Optional replacement name */
name?: string;
/** Optional index for ordering */
index?: number;
}Usage Example:
const { ReplaceSource } = require("webpack-sources");
// Access Replacement class
const ReplacementClass = ReplaceSource.Replacement;
// Create replacement manually (usually not needed)
const replacement = new ReplacementClass(0, 4, "const", "var-to-const");
console.log(replacement.start); // 0
console.log(replacement.end); // 4
console.log(replacement.content); // "const"
console.log(replacement.name); // "var-to-const"Interface for objects that can be used as sources in concatenation and other operations.
/**
* Interface for source-like objects that can be converted to Sources
*/
interface SourceLike {
/** Returns source content */
source(): string | Buffer;
/** Optional method to return content as Buffer */
buffer?(): Buffer;
/** Optional method to return size */
size?(): number;
/** Optional method to return source map */
map?(options?: MapOptions): RawSourceMap | null;
/** Optional method to return both source and map */
sourceAndMap?(options?: MapOptions): SourceAndMap;
/** Optional method to update hash */
updateHash?(hash: HashLike): void;
}Install with Tessl CLI
npx tessl i tessl/npm-webpack-sources