0
# Asset Transformation
1
2
The Transformer plugin enables custom processing of individual assets during the Parcel build process. Transformers handle parsing source code into ASTs, transforming assets, and generating final output code.
3
4
## Capabilities
5
6
### Transformer Class
7
8
Base class for creating asset transformation plugins.
9
10
```typescript { .api }
11
/**
12
* Base class for asset transformation plugins
13
* @template T - Configuration type for this transformer
14
*/
15
export declare class Transformer<T> {
16
constructor(opts: TransformerOpts<T>);
17
}
18
19
/**
20
* Transformer plugin configuration interface
21
* @template ConfigType - Type of configuration returned by loadConfig
22
*/
23
interface TransformerOpts<ConfigType> {
24
/** Load configuration for this transformer */
25
loadConfig?: (args: {
26
config: Config;
27
options: PluginOptions;
28
logger: PluginLogger;
29
tracer: PluginTracer;
30
}) => Promise<ConfigType> | ConfigType;
31
32
/** Check if an AST from a previous transformer can be reused */
33
canReuseAST?: (args: {
34
ast: AST;
35
options: PluginOptions;
36
logger: PluginLogger;
37
tracer: PluginTracer;
38
}) => boolean;
39
40
/** Parse asset contents into an AST */
41
parse?: (args: {
42
asset: Asset;
43
config: ConfigType;
44
resolve: ResolveFn;
45
options: PluginOptions;
46
logger: PluginLogger;
47
tracer: PluginTracer;
48
}) => Promise<AST | null> | AST | null;
49
50
/** Transform the asset and/or add new assets (required) */
51
transform(args: {
52
asset: MutableAsset;
53
config: ConfigType;
54
resolve: ResolveFn;
55
options: PluginOptions;
56
logger: PluginLogger;
57
tracer: PluginTracer;
58
}): Promise<Array<TransformerResult | MutableAsset>>;
59
60
/** Process assets after transformation */
61
postProcess?: (args: {
62
assets: Array<MutableAsset>;
63
config: ConfigType;
64
resolve: ResolveFn;
65
options: PluginOptions;
66
logger: PluginLogger;
67
tracer: PluginTracer;
68
}) => Promise<Array<TransformerResult>>;
69
70
/** Generate code from an AST */
71
generate?: (args: {
72
asset: Asset;
73
ast: AST;
74
options: PluginOptions;
75
logger: PluginLogger;
76
tracer: PluginTracer;
77
}) => Promise<GenerateResult>;
78
}
79
```
80
81
**Usage Example:**
82
83
```javascript
84
import { Transformer } from "@parcel/plugin";
85
86
export default new Transformer({
87
// Load transformer configuration
88
loadConfig({config, options, logger}) {
89
return config.getConfigFrom(/* config file path */);
90
},
91
92
// Check if AST can be reused
93
canReuseAST({ast}) {
94
return ast.type === 'expected-ast-type';
95
},
96
97
// Parse source code to AST
98
parse({asset, config}) {
99
const sourceCode = asset.getCode();
100
return parseToAST(sourceCode, config);
101
},
102
103
// Main transformation logic (required)
104
async transform({asset, config, resolve, logger}) {
105
const code = asset.getCode();
106
const transformedCode = await processCode(code, config);
107
108
asset.setCode(transformedCode);
109
asset.setMap(/* source map if needed */);
110
111
return [asset];
112
},
113
114
// Generate final code from AST
115
generate({asset, ast, options}) {
116
const generatedCode = generateCodeFromAST(ast);
117
return {
118
contents: generatedCode,
119
map: /* source map */
120
};
121
}
122
});
123
```
124
125
### Transformer Results
126
127
```typescript { .api }
128
/**
129
* Result from a transformation operation
130
*/
131
interface TransformerResult {
132
type: string;
133
contents: string;
134
uniqueKey?: string;
135
map?: SourceMap;
136
ast?: AST;
137
dependencies?: Array<Dependency>;
138
includedFiles?: Array<FilePath>;
139
env?: EnvironmentOptions;
140
meta?: Record<string, any>;
141
pipeline?: string;
142
symbols?: Map<Symbol, SymbolResolution>;
143
sideEffects?: boolean;
144
}
145
```
146
147
### Common Plugin Arguments
148
149
```typescript { .api }
150
/**
151
* Asset being processed
152
*/
153
interface Asset {
154
/** Get the asset's content as a string */
155
getCode(): string;
156
/** Get the asset's AST if available */
157
getAST(): Promise<AST | null>;
158
/** Get the asset's source map */
159
getMap(): Promise<SourceMap | null>;
160
/** Get asset metadata */
161
meta: Record<string, any>;
162
/** Asset file type */
163
type: string;
164
/** Asset file path */
165
filePath: FilePath;
166
}
167
168
/**
169
* Mutable asset for transformations
170
*/
171
interface MutableAsset extends Asset {
172
/** Set the asset's content */
173
setCode(code: string): void;
174
/** Set the asset's AST */
175
setAST(ast: AST): void;
176
/** Set the asset's source map */
177
setMap(map: SourceMap | null): void;
178
/** Add a dependency to this asset */
179
addDependency(dependency: DependencyOptions): Dependency;
180
/** Add an included file for invalidation */
181
addIncludedFile(filePath: FilePath): void;
182
}
183
184
/**
185
* Plugin options provided to all plugins
186
*/
187
interface PluginOptions {
188
/** Project root directory */
189
projectRoot: FilePath;
190
/** Input file system */
191
inputFS: FileSystem;
192
/** Output file system */
193
outputFS: FileSystem;
194
/** Package manager */
195
packageManager: PackageManager;
196
/** Build mode */
197
mode: "development" | "production";
198
/** Build environment */
199
env: EnvMap;
200
/** Hot module replacement options */
201
hmrOptions?: HMROptions;
202
/** Source map options */
203
sourceMaps: boolean;
204
}
205
206
/**
207
* Plugin logger for outputting messages
208
*/
209
interface PluginLogger {
210
/** Log an error */
211
error(message: string | Diagnostic): void;
212
/** Log a warning */
213
warn(message: string | Diagnostic): void;
214
/** Log info message */
215
info(message: string): void;
216
/** Log verbose message */
217
verbose(message: string): void;
218
}
219
220
/**
221
* Plugin tracer for performance monitoring
222
*/
223
interface PluginTracer {
224
/** Whether tracing is enabled */
225
enabled: boolean;
226
/** Create a new measurement */
227
createMeasurement(name: string, phase?: string): TraceMeasurement;
228
}
229
```