or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bundling.mdcompression.mdindex.mdnaming.mdoptimization.mdpackaging.mdreporting.mdresolution.mdruntime.mdtransformation.mdvalidation.md

bundling.mddocs/

0

# Bundle Generation

1

2

The Bundler plugin controls how assets are grouped into bundles and optimizes the bundle graph for performance, caching, and loading strategies. Bundlers determine the overall structure of the build output.

3

4

## Capabilities

5

6

### Bundler Class

7

8

Base class for creating bundle generation plugins.

9

10

```typescript { .api }

11

/**

12

* Base class for bundle generation plugins

13

* @template T - Configuration type for this bundler

14

*/

15

export declare class Bundler<T> {

16

constructor(opts: BundlerOpts<T>);

17

}

18

19

/**

20

* Bundler plugin configuration interface

21

* @template ConfigType - Type of configuration returned by loadConfig

22

*/

23

interface BundlerOpts<ConfigType> {

24

/** Load configuration for this bundler */

25

loadConfig?: (args: {

26

config: Config;

27

options: PluginOptions;

28

logger: PluginLogger;

29

tracer: PluginTracer;

30

}) => Promise<ConfigType> | ConfigType;

31

32

/** Create bundles from the asset graph (required) */

33

bundle(args: {

34

bundleGraph: MutableBundleGraph;

35

config: ConfigType;

36

options: PluginOptions;

37

logger: PluginLogger;

38

tracer: PluginTracer;

39

}): Promise<void>;

40

41

/** Optimize the bundle graph (required) */

42

optimize(args: {

43

bundleGraph: MutableBundleGraph;

44

config: ConfigType;

45

options: PluginOptions;

46

logger: PluginLogger;

47

}): Promise<void>;

48

}

49

```

50

51

**Usage Example:**

52

53

```javascript

54

import { Bundler } from "@parcel/plugin";

55

56

export default new Bundler({

57

// Load bundler configuration

58

loadConfig({config}) {

59

return {

60

minBundleSize: config.minBundleSize || 1000,

61

maxBundleSize: config.maxBundleSize || 100000,

62

splitChunks: config.splitChunks !== false

63

};

64

},

65

66

// Create bundles from assets (required)

67

async bundle({bundleGraph, config, logger}) {

68

// Get all assets

69

const assets = bundleGraph.getAssets();

70

71

// Create entry bundles

72

for (const entry of bundleGraph.getEntryAssets()) {

73

const bundle = bundleGraph.createBundle({

74

entryAsset: entry,

75

target: entry.env.context,

76

type: getOutputType(entry.type)

77

});

78

79

bundleGraph.addAssetToBundle(entry, bundle);

80

}

81

82

// Group related assets into shared bundles

83

if (config.splitChunks) {

84

await this.createSharedBundles(bundleGraph, config);

85

}

86

},

87

88

// Optimize bundle graph (required)

89

async optimize({bundleGraph, config, logger}) {

90

// Remove empty bundles

91

for (const bundle of bundleGraph.getBundles()) {

92

if (bundleGraph.getBundleAssets(bundle).length === 0) {

93

bundleGraph.removeBundle(bundle);

94

}

95

}

96

97

// Merge small bundles

98

await this.mergeSmallBundles(bundleGraph, config);

99

100

// Optimize bundle dependencies

101

await this.optimizeBundleDependencies(bundleGraph);

102

}

103

});

104

```

105

106

### Bundle Graph Operations

107

108

```typescript { .api }

109

/**

110

* Mutable bundle graph for creating and modifying bundles

111

*/

112

interface MutableBundleGraph {

113

/** Get all assets in the graph */

114

getAssets(): Array<Asset>;

115

116

/** Get entry assets */

117

getEntryAssets(): Array<Asset>;

118

119

/** Get all bundles */

120

getBundles(): Array<Bundle>;

121

122

/** Create a new bundle */

123

createBundle(options: CreateBundleOptions): Bundle;

124

125

/** Remove a bundle */

126

removeBundle(bundle: Bundle): void;

127

128

/** Add an asset to a bundle */

129

addAssetToBundle(asset: Asset, bundle: Bundle): void;

130

131

/** Remove an asset from a bundle */

132

removeAssetFromBundle(asset: Asset, bundle: Bundle): void;

133

134

/** Get assets in a specific bundle */

135

getBundleAssets(bundle: Bundle): Array<Asset>;

136

137

/** Create a dependency between bundles */

138

createBundleDependency(from: Bundle, to: Bundle): void;

139

140

/** Get bundles that depend on the given bundle */

141

getBundleDependents(bundle: Bundle): Array<Bundle>;

142

143

/** Get bundles that the given bundle depends on */

144

getBundleDependencies(bundle: Bundle): Array<Bundle>;

145

}

146

147

/**

148

* Options for creating a new bundle

149

*/

150

interface CreateBundleOptions {

151

/** Entry asset for the bundle */

152

entryAsset?: Asset;

153

154

/** Bundle target */

155

target: Target;

156

157

/** Bundle output type */

158

type: string;

159

160

/** Whether this bundle needs a stable name */

161

needsStableName?: boolean;

162

163

/** Bundle behavior */

164

bundleBehavior?: BundleBehavior;

165

166

/** Bundle priority */

167

priority?: BundlePriority;

168

169

/** Environment for this bundle */

170

env?: EnvironmentOptions;

171

}

172

173

/**

174

* Bundle priority levels

175

*/

176

type BundlePriority = "sync" | "parallel" | "lazy";

177

```

178

179

### Bundle Information

180

181

```typescript { .api }

182

/**

183

* A bundle in the bundle graph

184

*/

185

interface Bundle {

186

/** Bundle ID */

187

id: string;

188

189

/** Bundle type */

190

type: string;

191

192

/** Target environment */

193

target: Target;

194

195

/** Entry asset if this is an entry bundle */

196

entryAsset?: Asset;

197

198

/** Main entry asset */

199

mainEntryAsset?: Asset;

200

201

/** Bundle file path */

202

filePath?: FilePath;

203

204

/** Bundle name */

205

name?: string;

206

207

/** Bundle display name */

208

displayName?: string;

209

210

/** Bundle statistics */

211

stats: BundleStats;

212

213

/** Environment for this bundle */

214

env: Environment;

215

216

/** Whether this bundle needs a stable name */

217

needsStableName: boolean;

218

219

/** Bundle behavior */

220

bundleBehavior?: BundleBehavior;

221

222

/** Bundle metadata */

223

meta: Record<string, any>;

224

}

225

226

/**

227

* Bundle statistics

228

*/

229

interface BundleStats {

230

/** Bundle size in bytes */

231

size: number;

232

233

/** Time to create bundle */

234

time: number;

235

}

236

```

237

238

### Common Bundling Strategies

239

240

**Entry Point Bundling:**

241

```javascript

242

// Create a bundle for each entry point

243

for (const entry of bundleGraph.getEntryAssets()) {

244

const bundle = bundleGraph.createBundle({

245

entryAsset: entry,

246

target: entry.target,

247

type: getOutputType(entry.type),

248

needsStableName: true

249

});

250

251

bundleGraph.addAssetToBundle(entry, bundle);

252

}

253

```

254

255

**Code Splitting:**

256

```javascript

257

// Create shared bundles for common dependencies

258

const sharedAssets = findSharedAssets(bundleGraph);

259

if (sharedAssets.length > 0) {

260

const sharedBundle = bundleGraph.createBundle({

261

target: primaryTarget,

262

type: 'js',

263

bundleBehavior: 'inline'

264

});

265

266

for (const asset of sharedAssets) {

267

bundleGraph.addAssetToBundle(asset, sharedBundle);

268

}

269

}

270

```

271

272

**Size-based Optimization:**

273

```javascript

274

// Merge small bundles to reduce HTTP requests

275

const smallBundles = bundleGraph.getBundles().filter(bundle =>

276

bundle.stats.size < config.minBundleSize

277

);

278

279

for (const smallBundle of smallBundles) {

280

const targetBundle = findMergeTarget(smallBundle, bundleGraph);

281

if (targetBundle) {

282

mergeBundles(smallBundle, targetBundle, bundleGraph);

283

}

284

}

285

```