or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bundle-building.mdcomposition.mdconsumption.mdfunction-maps.mdgeneration.mdindex.mdutilities.md

bundle-building.mddocs/

0

# Bundle Building

1

2

Functionality for building source-mapped bundles by concatenating strings and their corresponding source maps, producing indexed source maps for efficient debugging.

3

4

## Capabilities

5

6

### BundleBuilder Class

7

8

Main class for building bundles with source maps by concatenating code sections and composing their source maps.

9

10

```javascript { .api }

11

/**

12

* Builds a source-mapped bundle by concatenating strings and their source maps

13

*/

14

class BundleBuilder {

15

/**

16

* Creates a new bundle builder

17

* @param file - Name of the output bundle file

18

*/

19

constructor(file: string);

20

21

/**

22

* Append code with optional source map to the bundle

23

* @param code - Code string to append

24

* @param map - Optional source map for the code

25

* @returns Self for method chaining

26

*/

27

append(code: string, map?: MixedSourceMap): this;

28

29

/**

30

* Get the concatenated code for the bundle

31

* @returns Complete bundle code

32

*/

33

getCode(): string;

34

35

/**

36

* Get the composed source map for the bundle

37

* @returns Indexed source map covering the entire bundle

38

*/

39

getMap(): MixedSourceMap;

40

}

41

```

42

43

**Usage Examples:**

44

45

```javascript

46

const { BundleBuilder } = require("metro-source-map");

47

48

// Create a bundle builder

49

const builder = new BundleBuilder("bundle.js");

50

51

// Append code sections with their source maps

52

builder

53

.append("// Header comment\n") // No source map

54

.append("console.log('module1');\n", module1SourceMap)

55

.append("console.log('module2');\n", module2SourceMap)

56

.append("// Footer\n"); // No source map

57

58

// Get the final bundle

59

const bundleCode = builder.getCode();

60

const bundleMap = builder.getMap();

61

62

console.log(bundleCode);

63

// Output:

64

// // Header comment

65

// console.log('module1');

66

// console.log('module2');

67

// // Footer

68

69

console.log(bundleMap.sections.length); // Number of source map sections

70

```

71

72

### Index Map Creation

73

74

Utility function for creating empty indexed source maps.

75

76

```javascript { .api }

77

/**

78

* Creates an indexed source map from file and sections

79

* @param file - File name for the source map

80

* @param sections - Array of source map sections with offsets

81

* @returns Indexed source map structure

82

*/

83

function createIndexMap(file: string, sections: Array<IndexMapSection>): IndexMap;

84

```

85

86

**Usage Examples:**

87

88

```javascript

89

const { createIndexMap } = require("metro-source-map");

90

91

// Create an index map with sections

92

const sections = [

93

{

94

offset: { line: 0, column: 0 },

95

map: someBasicSourceMap

96

}

97

];

98

const indexMap = createIndexMap("output.js", sections);

99

console.log(indexMap);

100

// {

101

// version: 3,

102

// sections: [...],

103

// file: "output.js"

104

// }

105

106

// Use with BundleBuilder for custom initialization

107

const builder = new BundleBuilder("custom.js");

108

// Builder internally uses createIndexMap

109

```

110

111

### Advanced Bundle Building

112

113

```javascript

114

const { BundleBuilder } = require("metro-source-map");

115

116

// Building a complex bundle with mixed content types

117

const builder = new BundleBuilder("app.bundle.js");

118

119

// Add a header without source map

120

builder.append("(function() {\n");

121

122

// Add main application modules with source maps

123

const modules = [

124

{ code: "var utils = require('./utils');\n", map: utilsSourceMap },

125

{ code: "var app = require('./app');\n", map: appSourceMap },

126

{ code: "app.start();\n", map: startSourceMap }

127

];

128

129

modules.forEach(({ code, map }) => {

130

builder.append(code, map);

131

});

132

133

// Add a footer without source map

134

builder.append("})();\n");

135

136

// Generate the final bundle

137

const result = {

138

code: builder.getCode(),

139

map: builder.getMap()

140

};

141

142

// The resulting map will be an indexed source map with sections

143

// corresponding to each piece of code that had an associated source map

144

console.log(result.map.sections.length); // Number of mapped sections

145

```

146

147

### Index Map Structure

148

149

```javascript { .api }

150

/**

151

* Indexed source map format for bundles

152

*/

153

interface IndexMap {

154

/** Source map version (always 3) */

155

version: number;

156

/** Output file name */

157

file?: string;

158

/** Array of source map sections */

159

sections: Array<IndexMapSection>;

160

/** Facebook extension: byte offsets */

161

x_facebook_offsets?: Array<number>;

162

/** Metro extension: module paths */

163

x_metro_module_paths?: Array<string>;

164

/** Facebook extension: segment map */

165

x_facebook_segments?: FBSegmentMap;

166

/** Hermes extension: function offsets */

167

x_hermes_function_offsets?: HermesFunctionOffsets;

168

/** These fields are void in IndexMap to maintain type safety */

169

mappings?: void;

170

sourcesContent?: void;

171

x_facebook_sources?: void;

172

x_google_ignoreList?: void;

173

}

174

175

/**

176

* Individual section within an indexed source map

177

*/

178

interface IndexMapSection {

179

/** Source map for this section (can be basic or indexed) */

180

map: IndexMap | BasicSourceMap;

181

/** Offset where this section starts in the bundle */

182

offset: {

183

/** Line offset (0-based) */

184

line: number;

185

/** Column offset (0-based) */

186

column: number;

187

};

188

}

189

```

190

191

### Integration with Source Map Types

192

193

```javascript

194

const { BundleBuilder, Generator, fromRawMappings } = require("metro-source-map");

195

196

// Building a bundle using generated source maps

197

const builder = new BundleBuilder("output.js");

198

199

// Generate source maps for individual modules

200

const module1Map = fromRawMappings([{

201

map: [[1, 0, 1, 0], [1, 8, 1, 8]],

202

path: "src/module1.js",

203

source: "console.log('one');",

204

code: "console.log('one');",

205

isIgnored: false

206

}]).toMap();

207

208

const module2Map = fromRawMappings([{

209

map: [[1, 0, 1, 0], [1, 8, 1, 8]],

210

path: "src/module2.js",

211

source: "console.log('two');",

212

code: "console.log('two');",

213

isIgnored: false

214

}]).toMap();

215

216

// Build the bundle

217

builder

218

.append("console.log('one');\n", module1Map)

219

.append("console.log('two');\n", module2Map);

220

221

const finalMap = builder.getMap();

222

// finalMap will be an IndexMap with 2 sections

223

```

224

225

## Error Handling

226

227

BundleBuilder operations may encounter errors in the following cases:

228

229

- **Invalid source maps**: When provided source maps are malformed

230

- **Empty builder**: When `getMap()` or `getCode()` is called before any content is appended

231

232

```javascript

233

const { BundleBuilder } = require("metro-source-map");

234

235

try {

236

const builder = new BundleBuilder("test.js");

237

builder.append("console.log('test');", invalidSourceMap);

238

const map = builder.getMap();

239

} catch (error) {

240

console.error('Bundle building failed:', error);

241

}

242

243

// Safe usage with validation

244

const builder = new BundleBuilder("safe.js");

245

if (someCode && someCode.length > 0) {

246

builder.append(someCode, optionalSourceMap);

247

}

248

```