Source map generator for Metro bundler with advanced mapping capabilities and Facebook/Hermes extensions.
npx @tessl/cli install tessl/npm-metro-source-map@0.83.0Metro Source Map is a comprehensive source map generation and consumption library designed for the Metro JavaScript bundler used in React Native development. It provides advanced source mapping capabilities including source map composition, bundle building with index maps, source map consumption and generation, function map generation for debugging support, and various encoding utilities for efficient source map storage.
npm install metro-source-mapconst {
BundleBuilder,
Consumer,
composeSourceMaps,
fromRawMappings,
fromRawMappingsNonBlocking,
generateFunctionMap,
functionMapBabelPlugin,
createIndexMap,
normalizeSourcePath,
toBabelSegments,
toSegmentTuple
} = require("metro-source-map");Note: This package uses CommonJS exports only. ES6 import syntax is not supported.
const { fromRawMappings, Consumer, BundleBuilder } = require("metro-source-map");
// Generate a source map from raw mappings
const modules = [
{
map: [[1, 0, 1, 0], [2, 0, 2, 0]], // [genLine, genCol, srcLine, srcCol]
functionMap: null,
path: "module1.js",
source: "console.log('hello');",
code: "console.log('hello');",
isIgnored: false
}
];
const generator = fromRawMappings(modules);
const sourceMap = generator.toMap("bundle.js");
// Consume a source map
const consumer = new Consumer(sourceMap);
const originalPosition = consumer.originalPositionFor({
line: 1,
column: 0
});
// Build a bundle with source maps
const builder = new BundleBuilder("output.js");
builder.append("console.log('hello');", someSourceMap);
const bundledCode = builder.getCode();
const bundledMap = builder.getMap();Metro Source Map is built around several key components:
Generator class for creating source maps from raw mappings with support for Facebook extensionsConsumer and related classes for reading and querying existing source mapsBundleBuilder for concatenating code with proper source map compositionCreate source maps from raw mappings with support for Metro's specific requirements and Facebook extensions.
function fromRawMappings(
modules: Array<{
map: ?Array<MetroSourceMapSegmentTuple>,
functionMap: ?FBSourceFunctionMap,
path: string,
source: string,
code: string,
isIgnored: boolean,
lineCount?: number
}>,
offsetLines?: number = 0
): Generator;
function fromRawMappingsNonBlocking(
modules: Array<{
map: ?Array<MetroSourceMapSegmentTuple>,
functionMap: ?FBSourceFunctionMap,
path: string,
source: string,
code: string,
isIgnored: boolean,
lineCount?: number
}>,
offsetLines?: number = 0
): Promise<Generator>;
// Generator class returned by fromRawMappings functions
class Generator {
startFile(file: string, code: string, functionMap?: FBSourceFunctionMap, flags?: FileFlags): void;
endFile(): void;
addSimpleMapping(generatedLine: number, generatedColumn: number): void;
addSourceMapping(generatedLine: number, generatedColumn: number, sourceLine: number, sourceColumn: number): void;
addNamedSourceMapping(generatedLine: number, generatedColumn: number, sourceLine: number, sourceColumn: number, name: string): void;
toMap(file?: string, options?: {excludeSource?: boolean}): BasicSourceMap;
toString(file?: string, options?: {excludeSource?: boolean}): string;
}Read and query source maps with support for both basic and indexed source map formats.
class Consumer {
static GENERATED_ORDER: IterationOrder;
static ORIGINAL_ORDER: IterationOrder;
static GREATEST_LOWER_BOUND: LookupBias;
static LEAST_UPPER_BOUND: LookupBias;
constructor(sourceMap: MixedSourceMap);
originalPositionFor(generatedPosition: GeneratedPositionLookup): SourcePosition;
generatedMappings(): Iterable<Mapping>;
eachMapping(callback: (mapping: Mapping) => mixed, context?: mixed, order?: IterationOrder): void;
get file(): ?string;
sourceContentFor(source: string, nullOnMissing: true): ?string;
}
interface SourcePosition {
source: ?string;
line: ?number;
column: ?number;
name: ?string;
}
interface GeneratedPositionLookup {
line: number;
column: number;
bias?: LookupBias;
}Build source-mapped bundles by concatenating strings and their corresponding source maps.
class BundleBuilder {
constructor(file: string);
append(code: string, map?: MixedSourceMap): this;
getCode(): string;
getMap(): MixedSourceMap;
}
function createIndexMap(file: string, sections: Array<IndexMapSection>): IndexMap;Compose multiple source maps into a single source map, useful for multi-stage transformations.
function composeSourceMaps(maps: Array<MixedSourceMap>): MixedSourceMap;Generate Facebook-specific function maps for enhanced debugging support in Hermes and React Native.
function generateFunctionMap(ast: BabelNode, context?: Context): FBSourceFunctionMap;
function functionMapBabelPlugin(): PluginObj;
interface FBSourceFunctionMap {
names: Array<string>;
mappings: string;
}
interface Context {
filename?: ?string;
}Additional utilities for source map manipulation and conversion.
function toBabelSegments(sourceMap: BasicSourceMap): Array<BabelSourceMapSegment>;
function toSegmentTuple(mapping: BabelSourceMapSegment): MetroSourceMapSegmentTuple;
function normalizeSourcePath(source: string, sourceRoot?: ?string): string;type MetroSourceMapSegmentTuple =
| [number, number] // GeneratedCodeMapping
| [number, number, number, number] // SourceMapping
| [number, number, number, number, string]; // SourceMappingWithName
interface BasicSourceMap {
file?: string;
mappings: string;
names: Array<string>;
sourceRoot?: string;
sources: Array<string>;
sourcesContent?: Array<?string>;
version: number;
x_facebook_offsets?: Array<number>;
x_metro_module_paths?: Array<string>;
x_facebook_sources?: FBSourcesArray;
x_facebook_segments?: FBSegmentMap;
x_hermes_function_offsets?: HermesFunctionOffsets;
x_google_ignoreList?: Array<number>;
}
interface IndexMapSection {
map: IndexMap | BasicSourceMap;
offset: {
line: number;
column: number;
};
}
interface IndexMap {
file?: string;
mappings?: void;
sourcesContent?: void;
sections: Array<IndexMapSection>;
version: number;
x_facebook_offsets?: Array<number>;
x_metro_module_paths?: Array<string>;
x_facebook_sources?: void;
x_facebook_segments?: FBSegmentMap;
x_hermes_function_offsets?: HermesFunctionOffsets;
x_google_ignoreList?: void;
}
type MixedSourceMap = IndexMap | BasicSourceMap;
interface HermesFunctionOffsets {
[number]: Array<number>;
}
type FBSourcesArray = Array<?FBSourceMetadata>;
type FBSourceMetadata = [?FBSourceFunctionMap];
interface FBSegmentMap {
[id: string]: MixedSourceMap;
}
interface FileFlags {
addToIgnoreList?: boolean;
}
// Additional types for external dependencies
type BabelNode = any; // From @babel/types
type PluginObj = any; // From Babel plugin system
type BabelSourceMapSegment = any; // From @babel/generator
type IterationOrder = number;
type LookupBias = number;
type Mapping = any;