0
# Bundle Compression
1
2
The Compressor plugin compresses bundle outputs using various compression algorithms to reduce file sizes for network transfer. Compressors operate on the final bundle contents.
3
4
## Capabilities
5
6
### Compressor Class
7
8
Base class for creating bundle compression plugins.
9
10
```typescript { .api }
11
/**
12
* Base class for bundle compression plugins
13
*/
14
export declare class Compressor {
15
constructor(opts: CompressorOpts);
16
}
17
18
/**
19
* Compressor plugin configuration interface
20
*/
21
interface CompressorOpts {
22
/** Compress bundle contents (required) */
23
compress(args: {
24
stream: Readable;
25
options: PluginOptions;
26
logger: PluginLogger;
27
tracer: PluginTracer;
28
}): Promise<{
29
stream: Readable;
30
type?: string;
31
} | null>;
32
}
33
```
34
35
**Usage Example:**
36
37
```javascript
38
import { Compressor } from "@parcel/plugin";
39
import { createGzip, createBrotliCompress } from "zlib";
40
import { pipeline } from "stream/promises";
41
42
export default new Compressor({
43
// Compress bundle contents (required)
44
async compress({stream, options, logger}) {
45
// Only compress in production
46
if (options.mode !== 'production') {
47
return null;
48
}
49
50
// Use Brotli compression for better compression ratio
51
if (this.supportsBrotli()) {
52
const compressedStream = createBrotliCompress({
53
level: 6, // Balance between compression and speed
54
flush: require('zlib').constants.BROTLI_OPERATION_FLUSH
55
});
56
57
// Create compressed stream
58
const compressed = stream.pipe(compressedStream);
59
60
return {
61
stream: compressed,
62
type: 'br' // Brotli encoding
63
};
64
}
65
66
// Fallback to Gzip
67
const gzipStream = createGzip({
68
level: 6,
69
flush: require('zlib').constants.Z_SYNC_FLUSH
70
});
71
72
const compressed = stream.pipe(gzipStream);
73
74
return {
75
stream: compressed,
76
type: 'gzip'
77
};
78
},
79
80
supportsBrotli() {
81
// Check if Brotli is available
82
try {
83
require('zlib').createBrotliCompress;
84
return true;
85
} catch {
86
return false;
87
}
88
}
89
});
90
```
91
92
### Stream Processing
93
94
```typescript { .api }
95
/**
96
* Readable stream interface
97
*/
98
interface Readable {
99
/** Read data from stream */
100
read(size?: number): Buffer | string | null;
101
102
/** Pipe to another stream */
103
pipe<T extends Writable>(destination: T): T;
104
105
/** Add event listeners */
106
on(event: string, listener: Function): this;
107
108
/** Remove event listeners */
109
off(event: string, listener: Function): this;
110
}
111
112
/**
113
* Writable stream interface
114
*/
115
interface Writable {
116
/** Write data to stream */
117
write(chunk: any): boolean;
118
119
/** End the stream */
120
end(): void;
121
}
122
```
123
124
### Compression Types
125
126
```typescript { .api }
127
/**
128
* Supported compression types
129
*/
130
type CompressionType =
131
| 'gzip' // Gzip compression
132
| 'br' // Brotli compression
133
| 'deflate' // Deflate compression
134
| 'lz4' // LZ4 compression
135
| 'zstd'; // Zstandard compression
136
```
137
138
### Advanced Compression Example
139
140
```javascript
141
import { Compressor } from "@parcel/plugin";
142
import { Transform } from "stream";
143
144
export default new Compressor({
145
async compress({stream, options}) {
146
// Custom compression with size checking
147
let totalSize = 0;
148
const sizeTracker = new Transform({
149
transform(chunk, encoding, callback) {
150
totalSize += chunk.length;
151
callback(null, chunk);
152
}
153
});
154
155
// Track original size
156
const trackedStream = stream.pipe(sizeTracker);
157
158
// Choose compression based on content type and size
159
const compressionLevel = this.getCompressionLevel(totalSize);
160
const algorithm = this.chooseAlgorithm(options);
161
162
const compressor = this.createCompressor(algorithm, compressionLevel);
163
const compressed = trackedStream.pipe(compressor);
164
165
return {
166
stream: compressed,
167
type: algorithm
168
};
169
},
170
171
getCompressionLevel(size) {
172
// Higher compression for larger files
173
if (size > 100000) return 9; // Maximum compression
174
if (size > 10000) return 6; // Balanced
175
return 3; // Fast compression for small files
176
},
177
178
chooseAlgorithm(options) {
179
// Choose best algorithm based on environment
180
if (options.target?.engines?.browsers) {
181
return 'gzip'; // Better browser support
182
}
183
return 'br'; // Better compression for modern environments
184
},
185
186
createCompressor(algorithm, level) {
187
switch (algorithm) {
188
case 'br':
189
return createBrotliCompress({ level });
190
case 'gzip':
191
return createGzip({ level });
192
default:
193
return createGzip({ level });
194
}
195
}
196
});
197
```