Source code handling classes for webpack and other build tools with optional source map support
—
Performance optimization through caching and memory management utilities, including string interning and dual buffer caching.
Decorates a Source with caching for expensive operations like source(), buffer(), size(), map(), and sourceAndMap(). Provides significant performance improvements through memoization.
/**
* Caches results of expensive Source operations
* @param source - Source to cache, or function returning Source
* @param cachedData - Optional pre-cached data
*/
class CachedSource extends Source {
constructor(source: Source | (() => Source), cachedData?: CachedData);
/** Returns cached data for serialization/persistence */
getCachedData(): CachedData;
/** Returns the original wrapped Source */
original(): Source;
/** Returns the original Source or the function that creates it */
originalLazy(): Source | (() => Source);
/** Streams chunks efficiently using cached data when possible */
streamChunks(
options: StreamChunksOptions,
onChunk: OnChunk,
onSource: OnSource,
onName: OnName
): GeneratedSourceInfo;
}Usage Examples:
const { CachedSource, SourceMapSource } = require("webpack-sources");
// Cache expensive source operations
const expensiveSource = new SourceMapSource(
largeSourceCode,
"large-file.js",
complexSourceMap
);
const cached = new CachedSource(expensiveSource);
// First call computes and caches
const content1 = cached.source(); // Slow - computes and caches
const size1 = cached.size(); // Fast - derived from cached source
// Subsequent calls use cache
const content2 = cached.source(); // Fast - from cache
const map = cached.map(); // Slow first time, fast after
// Lazy source creation
const lazyCached = new CachedSource(() => {
console.log("Creating source..."); // Only runs when needed
return new SourceMapSource(code, name, map);
});
// Source not created yet
const lazySize = lazyCached.size(); // Now source is created and cached
// Get cache data for persistence
const cacheData = cached.getCachedData();
// Later: new CachedSource(originalSource, cacheData)Structure containing cached results for efficient Source recreation.
/**
* Cached data structure for CachedSource serialization
*/
interface CachedData {
/** Whether source content is cached */
source?: boolean;
/** Cached buffer representation */
buffer: Buffer;
/** Cached size in bytes */
size?: number;
/** Cached source maps by options key */
maps: Map<string, BufferEntry>;
/** Cached hash components */
hash?: (string | Buffer)[];
}
/**
* Buffer entry for cached source maps
*/
interface BufferEntry {
/** Raw source map */
map?: RawSourceMap | null;
/** Buffered/optimized source map */
bufferedMap?: BufferedMap | null;
}
/**
* Optimized source map format with Buffer mappings
*/
interface BufferedMap {
/** Source map version */
version: number;
/** Source file names */
sources: string[];
/** Symbol names */
names: string[];
/** Optional source root */
sourceRoot?: string;
/** Source contents (may be Buffers for binary) */
sourcesContent?: ("" | Buffer)[];
/** Mappings as Buffer for efficiency */
mappings?: Buffer;
/** Generated file name */
file: string;
}Memory optimization utilities for string interning and dual string/buffer caching.
/**
* String and buffer optimization utilities
*/
interface StringBufferUtils {
/** Enables dual string/buffer caching optimization */
enableDualStringBufferCaching(): void;
/** Disables dual string/buffer caching to save memory */
disableDualStringBufferCaching(): void;
/** Checks if dual caching is currently enabled */
isDualStringBufferCachingEnabled(): boolean;
/**
* Interns string to save memory when same strings repeat
* Only interns strings >= 128 characters when interning is active
*/
internString(str: string): string;
/** Starts a string interning range for memory optimization */
enterStringInterningRange(): void;
/** Ends string interning range and cleans up interned strings */
exitStringInterningRange(): void;
}Usage Examples:
const { util: { stringBufferUtils } } = require("webpack-sources");
// Check current caching state
console.log(stringBufferUtils.isDualStringBufferCachingEnabled()); // true (default)
// Disable dual caching to save memory
stringBufferUtils.disableDualStringBufferCaching();
console.log(stringBufferUtils.isDualStringBufferCachingEnabled()); // false
// Re-enable for performance
stringBufferUtils.enableDualStringBufferCaching();
// String interning for memory optimization
stringBufferUtils.enterStringInterningRange();
const longString = "a".repeat(200);
const interned1 = stringBufferUtils.internString(longString);
const interned2 = stringBufferUtils.internString(longString);
console.log(interned1 === interned2); // true - same reference
// Clean up interned strings
stringBufferUtils.exitStringInterningRange();
// Nested interning ranges
stringBufferUtils.enterStringInterningRange(); // Range 1
stringBufferUtils.enterStringInterningRange(); // Range 2 (nested)
stringBufferUtils.exitStringInterningRange(); // End range 2
stringBufferUtils.exitStringInterningRange(); // End range 1, cleanup happensCaching Strategy:
const { CachedSource, RawSource } = require("webpack-sources");
// For sources that will be accessed multiple times
const frequentlyUsed = new CachedSource(
new RawSource(largeContent)
);
// For expensive sources with complex operations
const expensiveSource = new CachedSource(() => {
// Expensive computation only happens when needed
return new SourceMapSource(
processLargeFile(),
"processed.js",
generateComplexSourceMap()
);
});
// Persist cache data across sessions
const cacheData = frequentlyUsed.getCachedData();
// Save cacheData to disk...
// Later, restore from cache
const restored = new CachedSource(originalSource, cacheData);Memory Optimization:
const { util: { stringBufferUtils } } = require("webpack-sources");
// For processing many similar sources
stringBufferUtils.enterStringInterningRange();
try {
// Process many sources with repeated content
const sources = files.map(file => {
const content = stringBufferUtils.internString(file.content);
return new RawSource(content);
});
// Work with sources...
} finally {
// Always clean up
stringBufferUtils.exitStringInterningRange();
}
// Disable dual caching in memory-constrained environments
if (process.env.LOW_MEMORY) {
stringBufferUtils.disableDualStringBufferCaching();
}Install with Tessl CLI
npx tessl i tessl/npm-webpack-sources