0
# Asset Packaging
1
2
The Packager plugin packages bundles into final output formats for different target environments and module systems. Packagers handle the final step of converting internal bundle representations into files that can be executed or loaded.
3
4
## Capabilities
5
6
### Packager Class
7
8
Base class for creating asset packaging plugins.
9
10
```typescript { .api }
11
/**
12
* Base class for asset packaging plugins
13
* @template C - Configuration type
14
* @template B - Bundle configuration type
15
*/
16
export declare class Packager<C, B> {
17
constructor(opts: PackagerOpts<C, B>);
18
}
19
20
/**
21
* Packager plugin configuration interface
22
*/
23
interface PackagerOpts<ConfigType, BundleConfigType> {
24
/** Load global configuration */
25
loadConfig?: (args: {
26
config: Config;
27
options: PluginOptions;
28
logger: PluginLogger;
29
tracer: PluginTracer;
30
}) => Promise<ConfigType>;
31
32
/** Load bundle-specific configuration */
33
loadBundleConfig?: (args: {
34
bundle: NamedBundle;
35
bundleGraph: BundleGraph<NamedBundle>;
36
config: Config;
37
options: PluginOptions;
38
logger: PluginLogger;
39
tracer: PluginTracer;
40
}) => Promise<BundleConfigType>;
41
42
/** Package a bundle into final output (required) */
43
package(args: {
44
bundle: NamedBundle;
45
bundleGraph: BundleGraph<NamedBundle>;
46
options: PluginOptions;
47
logger: PluginLogger;
48
tracer: PluginTracer;
49
config: ConfigType;
50
bundleConfig: BundleConfigType;
51
getInlineBundleContents: (
52
bundle: Bundle,
53
bundleGraph: BundleGraph<NamedBundle>
54
) => Promise<{contents: Blob}>;
55
getSourceMapReference: (map?: SourceMap) => Promise<string | null>;
56
}): Promise<BundleResult | BundleResult[]>;
57
}
58
```
59
60
### Bundle Results
61
62
```typescript { .api }
63
/**
64
* Result from packaging a bundle
65
*/
66
interface BundleResult {
67
/** Output file contents */
68
contents: Blob;
69
70
/** Source map for the bundle */
71
map?: SourceMap;
72
73
/** Bundle type */
74
type?: string;
75
}
76
77
/**
78
* File contents as binary data
79
*/
80
type Blob = Buffer | Uint8Array | string;
81
```
82
83
**Usage Example:**
84
85
```javascript
86
import { Packager } from "@parcel/plugin";
87
88
export default new Packager({
89
// Package bundle into final output (required)
90
async package({
91
bundle,
92
bundleGraph,
93
getInlineBundleContents,
94
getSourceMapReference
95
}) {
96
const assets = bundleGraph.getBundleAssets(bundle);
97
let contents = '';
98
let sourceMaps = [];
99
100
// Package JavaScript bundle
101
if (bundle.type === 'js') {
102
// Add module wrapper
103
contents += '(function() {\n';
104
105
// Add each asset
106
for (const asset of assets) {
107
const assetCode = await asset.getCode();
108
const assetMap = await asset.getMap();
109
110
contents += `// Asset: ${asset.filePath}\n`;
111
contents += assetCode + '\n\n';
112
113
if (assetMap) {
114
sourceMaps.push(assetMap);
115
}
116
}
117
118
// Close module wrapper
119
contents += '})();';
120
121
// Generate combined source map
122
const combinedMap = this.combineMaps(sourceMaps);
123
const mapReference = await getSourceMapReference(combinedMap);
124
125
if (mapReference) {
126
contents += `\n//# sourceMappingURL=${mapReference}`;
127
}
128
129
return {
130
contents: contents,
131
map: combinedMap
132
};
133
}
134
135
// Handle other bundle types
136
return this.packageGeneric(assets);
137
},
138
139
combineMaps(maps) {
140
// Combine multiple source maps into one
141
// Implementation depends on source map library
142
return maps.length > 0 ? maps[0] : null;
143
},
144
145
packageGeneric(assets) {
146
// Default packaging for other file types
147
if (assets.length === 1) {
148
return {
149
contents: assets[0].getCode()
150
};
151
}
152
throw new Error('Cannot package multiple assets of this type');
153
}
154
});
155
```