0
# Code Optimization
1
2
The Optimizer plugin optimizes bundled code through minification, tree shaking, and other performance improvements. Optimizers transform bundle contents to reduce file size and improve runtime performance.
3
4
## Capabilities
5
6
### Optimizer Class
7
8
Base class for creating code optimization plugins.
9
10
```typescript { .api }
11
/**
12
* Base class for code optimization plugins
13
* @template C - Configuration type
14
* @template B - Bundle configuration type
15
*/
16
export declare class Optimizer<C, B> {
17
constructor(opts: OptimizerOpts<C, B>);
18
}
19
20
/**
21
* Optimizer plugin configuration interface
22
*/
23
interface OptimizerOpts<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
/** Optimize bundle contents (required) */
43
optimize(args: {
44
bundle: NamedBundle;
45
contents: Blob;
46
map?: SourceMap;
47
options: PluginOptions;
48
logger: PluginLogger;
49
tracer: PluginTracer;
50
config: ConfigType;
51
bundleConfig: BundleConfigType;
52
getSourceMapReference: (map?: SourceMap) => Promise<string | null>;
53
}): Promise<BundleResult | BundleResult[]>;
54
}
55
```
56
57
**Usage Example:**
58
59
```javascript
60
import { Optimizer } from "@parcel/plugin";
61
import { minify } from "terser"; // Example minifier
62
63
export default new Optimizer({
64
// Load optimization configuration
65
loadConfig({config}) {
66
return {
67
minify: config.minify !== false,
68
mangle: config.mangle !== false,
69
compress: config.compress !== false,
70
sourceMap: config.sourceMap !== false
71
};
72
},
73
74
// Optimize bundle contents (required)
75
async optimize({
76
bundle,
77
contents,
78
map,
79
config,
80
getSourceMapReference,
81
options
82
}) {
83
// Only optimize in production mode
84
if (options.mode !== 'production') {
85
return { contents, map };
86
}
87
88
// Optimize JavaScript bundles
89
if (bundle.type === 'js' && config.minify) {
90
const code = contents.toString();
91
92
const result = await minify(code, {
93
mangle: config.mangle,
94
compress: config.compress,
95
sourceMap: config.sourceMap && map ? {
96
content: map,
97
filename: bundle.filePath,
98
url: bundle.filePath + '.map'
99
} : false
100
});
101
102
if (result.error) {
103
throw new Error(`Minification failed: ${result.error}`);
104
}
105
106
let optimizedContents = result.code;
107
108
// Add source map reference
109
if (result.map && config.sourceMap) {
110
const mapRef = await getSourceMapReference(result.map);
111
if (mapRef) {
112
optimizedContents += `\n//# sourceMappingURL=${mapRef}`;
113
}
114
}
115
116
return {
117
contents: optimizedContents,
118
map: result.map
119
};
120
}
121
122
// Optimize CSS bundles
123
if (bundle.type === 'css' && config.minify) {
124
return this.optimizeCSS(contents, map, config);
125
}
126
127
// Return unoptimized for other types
128
return { contents, map };
129
},
130
131
async optimizeCSS(contents, map, config) {
132
// CSS optimization implementation
133
const minified = contents.toString()
134
.replace(/\s+/g, ' ') // Collapse whitespace
135
.replace(/;\s*}/g, '}') // Remove trailing semicolons
136
.replace(/\s*{\s*/g, '{') // Clean braces
137
.replace(/\s*}\s*/g, '}')
138
.replace(/\s*;\s*/g, ';') // Clean semicolons
139
.replace(/\s*,\s*/g, ',') // Clean commas
140
.trim();
141
142
return {
143
contents: minified,
144
map: map // Preserve existing source map
145
};
146
}
147
});
148
```