0
# Code Transformations
1
2
TypeScript transformers for Angular-specific code modifications including resource replacement, import elision, and JIT support removal.
3
4
## Capabilities
5
6
### Resource Replacement Transformer
7
8
Transforms Angular component decorators to replace template and style URLs with webpack imports or direct content.
9
10
```typescript { .api }
11
/**
12
* Creates transformer to replace Angular component resources
13
* Replaces templateUrl and styleUrls with webpack imports or direct content
14
* @param shouldTransform - Function to determine if file should be transformed
15
* @param getTypeChecker - Function to get TypeScript type checker
16
* @param inlineStyleFileExtension - Optional file extension for inline styles
17
* @returns TypeScript transformer factory
18
*/
19
function replaceResources(
20
shouldTransform: (fileName: string) => boolean,
21
getTypeChecker: () => ts.TypeChecker,
22
inlineStyleFileExtension?: string
23
): ts.TransformerFactory<ts.SourceFile>;
24
```
25
26
**Usage Example:**
27
28
```typescript
29
import { replaceResources } from '@ngtools/webpack';
30
31
const transformer = replaceResources(
32
(fileName) => fileName.endsWith('.component.ts'),
33
() => typeChecker,
34
'scss'
35
);
36
37
// Original component
38
@Component({
39
selector: 'app-example',
40
templateUrl: './example.component.html',
41
styleUrls: ['./example.component.scss']
42
})
43
44
// Transformed (with directTemplateLoading: false)
45
@Component({
46
selector: 'app-example',
47
template: require('./example.component.html?ngResource'),
48
styles: [require('./example.component.scss?ngResource')]
49
})
50
```
51
52
### Import Elision Transformer
53
54
Removes unused imports from TypeScript source files after other transformations have removed references.
55
56
```typescript { .api }
57
/**
58
* Removes imports for which all identifiers have been removed
59
* Works with type checker to identify unused imports after transformations
60
* @param sourceFile - TypeScript source file to process
61
* @param removedNodes - Array of nodes that have been removed by other transformers
62
* @param getTypeChecker - Function to get TypeScript type checker
63
* @param compilerOptions - TypeScript compiler options
64
* @returns Set of import nodes to remove
65
*/
66
function elideImports(
67
sourceFile: ts.SourceFile,
68
removedNodes: ts.Node[],
69
getTypeChecker: () => ts.TypeChecker,
70
compilerOptions: ts.CompilerOptions
71
): Set<ts.Node>;
72
```
73
74
**Usage Example:**
75
76
```typescript
77
import { elideImports } from '@ngtools/webpack';
78
79
// After other transformers have removed code
80
const removedImports = elideImports(
81
sourceFile,
82
removedNodes,
83
() => typeChecker,
84
compilerOptions
85
);
86
87
// Original file
88
import { Component, OnInit, ViewChild } from '@angular/core';
89
import { HttpClient } from '@angular/common/http';
90
91
// If OnInit and ViewChild were removed by other transformers
92
// Result after elision:
93
import { Component } from '@angular/core';
94
// HttpClient import removed if unused
95
```
96
97
### JIT Support Removal Transformer
98
99
Removes Ivy JIT support calls from compiled Angular applications for production builds.
100
101
```typescript { .api }
102
/**
103
* Removes Ivy JIT support calls from compiled code
104
* Optimizes production builds by removing development-only code
105
* @param shouldTransform - Function to determine if file should be transformed
106
* @returns TypeScript transformer factory
107
*/
108
function removeIvyJitSupportCalls(
109
shouldTransform: (fileName: string) => boolean
110
): ts.TransformerFactory<ts.SourceFile>;
111
```
112
113
**Usage Example:**
114
115
```typescript
116
import { removeIvyJitSupportCalls } from '@ngtools/webpack';
117
118
const transformer = removeIvyJitSupportCalls(
119
(fileName) => !fileName.includes('node_modules')
120
);
121
122
// Removes calls like:
123
// ɵɵsetClassMetadata, ɵɵsetNgModuleScope, etc.
124
```
125
126
### Image Domain Discovery Transformer
127
128
Discovers and collects image domains from Angular applications for optimization purposes.
129
130
```typescript { .api }
131
/**
132
* Finds and collects image domains from Angular applications
133
* Populates the global imageDomains set during compilation
134
* @param imageDomains - Set to populate with discovered domains
135
* @returns TypeScript transformer factory
136
*/
137
function findImageDomains(imageDomains: Set<string>): ts.TransformerFactory<ts.SourceFile>;
138
```
139
140
**Usage Example:**
141
142
```typescript
143
import { findImageDomains, imageDomains } from '@ngtools/webpack';
144
145
const transformer = findImageDomains(imageDomains);
146
147
// Automatically discovers domains from:
148
// <img src="https://example.com/image.jpg">
149
// backgroundImage: 'url(https://cdn.example.com/bg.png)'
150
```
151
152
### AOT Transformer Creation
153
154
Creates complete set of transformers for Angular AOT compilation.
155
156
```typescript { .api }
157
/**
158
* Creates transformers for Angular AOT compilation
159
* Includes all necessary transformers for production AOT builds
160
* @param compilerHost - Angular compiler host
161
* @param compilerOptions - Angular compiler options
162
* @param program - TypeScript program
163
* @param angularCompilerOptions - Angular-specific compiler options
164
* @returns Object containing before and after transformers
165
*/
166
function createAotTransformers(
167
compilerHost: CompilerHost,
168
compilerOptions: CompilerOptions,
169
program: ts.Program,
170
angularCompilerOptions: AngularCompilerOptions
171
): {
172
before: ts.TransformerFactory<ts.SourceFile>[];
173
after: ts.TransformerFactory<ts.SourceFile>[];
174
};
175
```
176
177
### JIT Transformer Creation
178
179
Creates transformers for Angular JIT compilation mode.
180
181
```typescript { .api }
182
/**
183
* Creates transformers for Angular JIT compilation
184
* Includes transformers needed for JIT development builds
185
* @param compilerHost - Angular compiler host
186
* @param compilerOptions - Angular compiler options
187
* @param program - TypeScript program
188
* @param angularCompilerOptions - Angular-specific compiler options
189
* @returns Object containing before and after transformers
190
*/
191
function createJitTransformers(
192
compilerHost: CompilerHost,
193
compilerOptions: CompilerOptions,
194
program: ts.Program,
195
angularCompilerOptions: AngularCompilerOptions
196
): {
197
before: ts.TransformerFactory<ts.SourceFile>[];
198
after: ts.TransformerFactory<ts.SourceFile>[];
199
};
200
```
201
202
### Transformer Merging
203
204
Utility for merging multiple transformer collections.
205
206
```typescript { .api }
207
/**
208
* Merges multiple transformer collections into a single collection
209
* Combines before and after transformers from multiple sources
210
* @param transformers - Array of transformer collections to merge
211
* @returns Merged transformer collection
212
*/
213
function mergeTransformers(
214
transformers: Array<{
215
before?: ts.TransformerFactory<ts.SourceFile>[];
216
after?: ts.TransformerFactory<ts.SourceFile>[];
217
}>
218
): {
219
before: ts.TransformerFactory<ts.SourceFile>[];
220
after: ts.TransformerFactory<ts.SourceFile>[];
221
};
222
```
223
224
### Bootstrap Replacement
225
226
Transforms application bootstrap code for different compilation modes.
227
228
```typescript { .api }
229
/**
230
* Replaces bootstrap code in Angular applications
231
* Modifies main.ts and similar bootstrap files for different compilation modes
232
* @param shouldTransform - Function to determine if file should be transformed
233
* @param getEntryModule - Function to get the entry module information
234
* @param getTypeChecker - Function to get TypeScript type checker
235
* @returns TypeScript transformer factory
236
*/
237
function replaceBootstrap(
238
shouldTransform: (fileName: string) => boolean,
239
getEntryModule: () => { path: string; className: string } | null,
240
getTypeChecker: () => ts.TypeChecker
241
): ts.TransformerFactory<ts.SourceFile>;
242
```
243
244
### Complete Transformation Pipeline Example
245
246
Example showing how transformers are used together:
247
248
```typescript
249
import {
250
createAotTransformers,
251
createJitTransformers,
252
mergeTransformers,
253
replaceResources,
254
elideImports,
255
removeIvyJitSupportCalls,
256
findImageDomains,
257
imageDomains
258
} from '@ngtools/webpack';
259
260
// Create base transformers based on compilation mode
261
const baseTransformers = jitMode
262
? createJitTransformers(host, options, program, angularOptions)
263
: createAotTransformers(host, options, program, angularOptions);
264
265
// Create additional transformers
266
const resourceTransformer = replaceResources(
267
(fileName) => fileName.endsWith('.component.ts'),
268
() => typeChecker,
269
'scss'
270
);
271
272
const domainTransformer = findImageDomains(imageDomains);
273
274
const jitRemovalTransformer = removeIvyJitSupportCalls(
275
(fileName) => !fileName.includes('node_modules')
276
);
277
278
// Merge all transformers
279
const allTransformers = mergeTransformers([
280
baseTransformers,
281
{
282
before: [resourceTransformer, domainTransformer],
283
after: [jitRemovalTransformer]
284
}
285
]);
286
287
// Apply transformers during TypeScript compilation
288
const result = ts.transpileModule(sourceCode, {
289
compilerOptions,
290
transformers: allTransformers
291
});
292
```
293
294
### Transformation Order
295
296
Transformers are applied in specific order for optimal results:
297
298
1. **Before transformers** (applied before TypeScript emit):
299
- Resource replacement (`replaceResources`)
300
- Image domain discovery (`findImageDomains`)
301
- Angular AOT/JIT transformers
302
- Bootstrap replacement (`replaceBootstrap`)
303
304
2. **After transformers** (applied after TypeScript emit):
305
- JIT support removal (`removeIvyJitSupportCalls`)
306
- Import elision (`elideImports`)
307
308
### Performance Considerations
309
310
Transformers include optimizations for build performance:
311
312
```typescript
313
// Selective transformation based on file type
314
const shouldTransform = (fileName: string) => {
315
return fileName.endsWith('.component.ts') ||
316
fileName.endsWith('.module.ts') ||
317
fileName.includes('/src/');
318
};
319
320
// Use cached type checker
321
let cachedTypeChecker: ts.TypeChecker;
322
const getTypeChecker = () => {
323
return cachedTypeChecker || (cachedTypeChecker = program.getTypeChecker());
324
};
325
```