or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# Parcel Raw URL Packager

1

2

The @parcel/packager-raw-url package is a specialized Parcel packager plugin that handles raw URL assets by preserving their original URL references without applying any transformations. It ensures raw bundles maintain their absolute URL paths and contain exactly one asset per bundle.

3

4

## Package Information

5

6

- **Package Name**: @parcel/packager-raw-url

7

- **Package Type**: npm

8

- **Language**: JavaScript (Flow)

9

- **Installation**: `npm install @parcel/packager-raw-url`

10

- **Parcel Version**: Requires Parcel ^2.15.4

11

- **Node.js**: Requires Node.js >= 16.0.0

12

13

## Core Imports

14

15

```javascript

16

import RawUrlPackager from "@parcel/packager-raw-url";

17

```

18

19

For CommonJS:

20

21

```javascript

22

const RawUrlPackager = require("@parcel/packager-raw-url");

23

```

24

25

For Flow type annotations:

26

27

```flow

28

import type {Packager} from "@parcel/plugin";

29

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

30

import {replaceURLReferences} from "@parcel/utils";

31

```

32

33

## Basic Usage

34

35

This package is typically used through Parcel's plugin system rather than directly in application code. Parcel automatically uses this packager for raw URL asset types.

36

37

```javascript

38

// Parcel configuration (.parcelrc)

39

{

40

"extends": "@parcel/config-default",

41

"packagers": {

42

"raw-url:*": "@parcel/packager-raw-url"

43

}

44

}

45

```

46

47

## Architecture

48

49

The raw URL packager is built as a Parcel plugin that integrates with Parcel's bundling pipeline:

50

51

- **Plugin Architecture**: Extends Parcel's `Packager` base class from `@parcel/plugin`

52

- **Bundle Processing**: Handles bundles containing raw URL assets

53

- **URL Preservation**: Uses `@parcel/utils` URL replacement utilities to maintain absolute URLs

54

- **Single Asset Validation**: Enforces constraint that raw bundles contain exactly one asset

55

56

## Capabilities

57

58

### Raw URL Packager Plugin

59

60

The default export is a Packager plugin instance configured specifically for raw URL asset handling.

61

62

```flow { .api }

63

/**

64

* Default export: Packager plugin instance for raw URL assets

65

* Automatically configured with package method for processing raw URL bundles

66

*/

67

declare const RawUrlPackager: Packager;

68

69

/**

70

* Package method configuration within the Packager instance

71

* @param bundle - Bundle object containing assets to process

72

* @param bundleGraph - Complete bundle graph for URL resolution

73

* @returns Promise resolving to object with processed contents

74

*/

75

interface PackageMethodParams {

76

bundle: Bundle;

77

bundleGraph: BundleGraph;

78

}

79

80

interface PackageMethodReturn {

81

contents: string;

82

}

83

84

/**

85

* Internal package method (not directly callable)

86

* Processes raw URL bundles by preserving original URLs

87

*/

88

function package(params: PackageMethodParams): Promise<PackageMethodReturn>;

89

90

/**

91

* Utility function from @parcel/utils used for URL replacement

92

* Replaces URL references in asset contents with bundle URLs

93

*/

94

function replaceURLReferences({

95

bundle,

96

bundleGraph,

97

contents,

98

relative = true,

99

map,

100

getReplacement = s => s,

101

}: {|

102

bundle: Bundle,

103

bundleGraph: BundleGraph<Bundle>,

104

contents: string,

105

relative?: boolean,

106

map?: ?SourceMap,

107

getReplacement?: string => string,

108

|}): {|+contents: string, +map: ?SourceMap|};

109

```

110

111

## Types

112

113

```flow { .api }

114

/**

115

* Bundle object representing a collection of assets

116

* Provided by Parcel's bundling system

117

*/

118

interface Bundle {

119

/** The bundle id */

120

+id: string;

121

/** The type of the bundle */

122

+type: string;

123

/** The environment of the bundle */

124

+env: Environment;

125

/** The bundle's target */

126

+target: Target;

127

/** Indicates that the bundle's file name should be stable over time */

128

+needsStableName: ?boolean;

129

/** Controls the behavior of the bundle (inline, isolated) */

130

+bundleBehavior: ?BundleBehavior;

131

/** Whether the bundle can be split */

132

+isSplittable: ?boolean;

133

/** A placeholder for the bundle's content hash */

134

+hashReference: string;

135

/** Returns the assets that are executed immediately when the bundle is loaded */

136

getEntryAssets(): Array<Asset>;

137

/** Returns the main entry of the bundle, which will provide the bundle's exports */

138

getMainEntry(): ?Asset;

139

/** Returns whether the bundle includes the given asset */

140

hasAsset(asset: Asset): boolean;

141

/** Returns whether the bundle includes the given dependency */

142

hasDependency(dependency: Dependency): boolean;

143

/** Traverses the assets in the bundle */

144

traverseAssets<TContext>(

145

visit: GraphVisitor<Asset, TContext>,

146

startAsset?: Asset,

147

): ?TContext;

148

/** Traverses assets and dependencies in the bundle */

149

traverse<TContext>(

150

visit: GraphVisitor<BundleTraversable, TContext>,

151

): ?TContext;

152

/** Returns a hash of the contents of the bundle */

153

getContentHash(): string;

154

}

155

156

/**

157

* Asset object representing a single bundled asset

158

* Provided by Parcel's asset system

159

*/

160

interface Asset {

161

/** The id of the asset */

162

+id: string;

163

/** The file system where the source is located */

164

+fs: FileSystem;

165

/** The file path of the asset */

166

+filePath: FilePath;

167

/** The asset's type. This initially corresponds to the source file extension */

168

+type: string;

169

/** The transformer options for the asset from the dependency query string */

170

+query: URLSearchParams;

171

/** The environment of the asset */

172

+env: Environment;

173

/** Whether this asset is part of the project, and not an external dependency */

174

+isSource: boolean;

175

/** Plugin-specific metadata for the asset */

176

+meta: Meta;

177

/** Controls which bundle the asset is placed into (inline, isolated) */

178

+bundleBehavior: ?BundleBehavior;

179

/** If the asset is used as a bundle entry, controls whether that bundle can be split */

180

+isBundleSplittable: boolean;

181

/** Whether this asset can be omitted if none of its exports are being used */

182

+sideEffects: boolean;

183

/** Unique key to identify assets when a transformer returns multiple assets */

184

+uniqueKey: ?string;

185

/** The type of the AST */

186

+astGenerator: ?ASTGenerator;

187

/** The pipeline defined in .parcelrc that the asset should be processed with */

188

+pipeline: ?string;

189

/** The symbols that the asset exports */

190

+symbols: AssetSymbols;

191

/** Statistics about the asset */

192

+stats: Stats;

193

/** Returns the current AST */

194

getAST(): Promise<?AST>;

195

/** Returns the asset contents as a string */

196

getCode(): Promise<string>;

197

/** Returns the asset contents as a buffer */

198

getBuffer(): Promise<Buffer>;

199

/** Returns the asset contents as a stream */

200

getStream(): Readable;

201

/** Returns the source map for the asset, if available */

202

getMap(): Promise<?SourceMap>;

203

/** Returns a buffer representation of the source map, if available */

204

getMapBuffer(): Promise<?Buffer>;

205

/** Returns a list of dependencies for the asset */

206

getDependencies(): $ReadOnlyArray<Dependency>;

207

}

208

209

/**

210

* BundleGraph object representing the complete bundle graph

211

* Used for URL resolution and bundle relationships

212

*/

213

interface BundleGraph<TBundle: Bundle> {

214

/** Retrieves an asset by id */

215

getAssetById(id: string): Asset;

216

/** Returns the public (short) id for an asset */

217

getAssetPublicId(asset: Asset): string;

218

/** Returns a list of bundles in the bundle graph. By default, inline bundles are excluded */

219

getBundles(opts?: {|includeInline: boolean|}): Array<TBundle>;

220

/** Traverses the assets and dependencies in the bundle graph, in depth first order */

221

traverse<TContext>(

222

visit: GraphVisitor<BundleGraphTraversable, TContext>,

223

startAsset: ?Asset,

224

options?: {|skipUnusedDependencies?: boolean|},

225

): ?TContext;

226

/** Traverses all bundles in the bundle graph, including inline bundles, in depth first order */

227

traverseBundles<TContext>(

228

visit: GraphVisitor<TBundle, TContext>,

229

startBundle: ?Bundle,

230

): ?TContext;

231

/** Returns a list of bundle groups that load the given bundle */

232

getBundleGroupsContainingBundle(bundle: Bundle): Array<BundleGroup>;

233

/** Returns a list of bundles that load together in the given bundle group */

234

getBundlesInBundleGroup(

235

bundleGroup: BundleGroup,

236

opts?: {|

237

recursive?: boolean,

238

includeInline?: boolean,

239

includeIsolated?: boolean,

240

|},

241

): Array<TBundle>;

242

/** Returns a list of bundles that this bundle loads asynchronously */

243

getChildBundles(bundle: Bundle): Array<TBundle>;

244

/** Returns a list of bundles that load this bundle asynchronously */

245

getParentBundles(bundle: Bundle): Array<TBundle>;

246

/** Returns whether the bundle was loaded by another bundle of the given type */

247

hasParentBundleOfType(bundle: Bundle, type: string): boolean;

248

/** Returns a list of bundles that are referenced by this bundle */

249

getReferencedBundles(

250

bundle: Bundle,

251

opts?: {|

252

recursive?: boolean,

253

includeInline?: boolean,

254

includeIsolated?: boolean,

255

|},

256

): Array<TBundle>;

257

/** Returns a list of bundles that reference this bundle */

258

getReferencingBundles(bundle: Bundle): Array<TBundle>;

259

/** Get the dependencies that the asset requires */

260

getDependencies(asset: Asset): Array<Dependency>;

261

/** Get the dependencies that require the asset */

262

getIncomingDependencies(asset: Asset): Array<Dependency>;

263

/** Get the asset that created the dependency */

264

getAssetWithDependency(dep: Dependency): ?Asset;

265

/** Returns whether the given bundle group is an entry */

266

isEntryBundleGroup(bundleGroup: BundleGroup): boolean;

267

/** Returns whether a dependency was excluded because it had no used symbols */

268

isDependencySkipped(dependency: Dependency): boolean;

269

/** Returns the asset that the dependency resolved to */

270

getResolvedAsset(dependency: Dependency, bundle: ?Bundle): ?Asset;

271

/** Returns the bundle that a dependency in a given bundle references, if any */

272

getReferencedBundle(dependency: Dependency, bundle: Bundle): ?TBundle;

273

/** Returns a list of bundles that contain the given asset */

274

getBundlesWithAsset(asset: Asset): Array<TBundle>;

275

/** Returns a list of bundles that contain the given dependency */

276

getBundlesWithDependency(dependency: Dependency): Array<TBundle>;

277

/** Returns whether the given asset is reachable in a sibling or all possible ancestries of the given bundle */

278

isAssetReachableFromBundle(asset: Asset, bundle: Bundle): boolean;

279

/** Returns whether an asset is referenced outside the given bundle */

280

isAssetReferenced(bundle: Bundle, asset: Asset): boolean;

281

/** Returns a list of entry bundles */

282

getEntryBundles(): Array<TBundle>;

283

}

284

285

/**

286

* Packager base class from @parcel/plugin

287

* Base class for all Parcel packager plugins

288

*/

289

interface Packager {

290

// Packager implementation details handled by Parcel

291

}

292

293

// Supporting types used throughout the API

294

type Async<T> = T | Promise<T>;

295

type FilePath = string;

296

type Meta = {[string]: mixed};

297

type BundleBehavior = "inline" | "isolated";

298

299

interface Environment {

300

context: "node" | "browser" | "web-worker" | "service-worker" | "electron-main" | "electron-renderer";

301

engines: {[string]: string};

302

includeNodeModules: boolean | Array<string> | {[string]: boolean};

303

outputFormat: "global" | "esmodule" | "commonjs";

304

isLibrary: boolean;

305

shouldOptimize: boolean;

306

shouldScopeHoist: boolean;

307

sourceMap?: SourceMapOptions;

308

}

309

310

interface Target {

311

name: string;

312

distDir: FilePath;

313

distEntry?: ?FilePath;

314

publicUrl: string;

315

env: Environment;

316

sourceMap?: ?SourceMapOptions;

317

}

318

319

interface Dependency {

320

id: string;

321

specifier: string;

322

specifierType: DependencySpecifierType;

323

priority: DependencyPriority;

324

needsStableName: boolean;

325

bundleBehavior: ?BundleBehavior;

326

isEntry: boolean;

327

isOptional: boolean;

328

loc: ?SourceLocation;

329

env: Environment;

330

meta: Meta;

331

target: ?Target;

332

sourceAssetId: ?string;

333

sourcePath: ?FilePath;

334

resolveFrom: ?FilePath;

335

range: ?SemverRange;

336

symbols: ?Map<Symbol, {|local: Symbol, loc: ?SourceLocation, isWeak: boolean, meta?: ?Meta|}>;

337

pipeline: ?string;

338

}

339

340

interface BundleGroup {

341

target: Target;

342

entryAssetId: string;

343

}

344

345

interface Stats {

346

time: number;

347

size: number;

348

}

349

350

interface SourceMap {

351

// Source map structure

352

}

353

354

interface FileSystem {

355

// File system interface

356

}

357

358

interface AssetSymbols {

359

// Asset symbols structure

360

}

361

362

interface ASTGenerator {

363

// AST generator interface

364

}

365

366

interface AST {

367

// Abstract syntax tree structure

368

}

369

370

interface Buffer {

371

// Node.js Buffer interface

372

}

373

374

interface Readable {

375

// Node.js Readable stream interface

376

}

377

378

type GraphVisitor<TNode, TContext> = (

379

node: TNode,

380

context: ?TContext,

381

actions: TraversalActions,

382

) => ?TContext;

383

384

interface TraversalActions {

385

skipChildren(): void;

386

stop(): void;

387

}

388

389

type BundleTraversable = Asset | Dependency;

390

type BundleGraphTraversable = Asset | Dependency;

391

392

type DependencySpecifierType = "esm" | "commonjs" | "url" | "custom";

393

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

394

type Symbol = string;

395

type SourceLocation = {|

396

filePath: FilePath,

397

start: {|line: number, column: number|},

398

end: {|line: number, column: number|},

399

|};

400

type SemverRange = string;

401

type SourceMapOptions = {|

402

inline?: boolean,

403

inlineSources?: boolean,

404

sourceRoot?: string,

405

|};

406

```

407

408

## Implementation Details

409

410

### Bundle Validation

411

412

The packager enforces that raw URL bundles contain exactly one asset:

413

414

- Throws assertion error if bundle contains zero or multiple assets

415

- Uses Node.js `assert.equal` for validation

416

- Ensures bundle integrity for raw URL processing

417

418

### URL Reference Processing

419

420

URL references are processed using Parcel's utility functions:

421

422

- Uses `replaceURLReferences` from `@parcel/utils`

423

- Sets `relative: false` to maintain absolute URL paths

424

- Uses identity function `s => s` for URL replacement (no transformation)

425

- Preserves original URL structure in final bundle output

426

427

### Error Handling

428

429

- **Bundle Validation Error**: Throws `AssertionError` when bundle doesn't contain exactly one asset

430

- **Asset Processing Error**: Propagates errors from asset code retrieval

431

- **URL Processing Error**: Propagates errors from URL reference replacement