0
# Dependency Management
1
2
Functions for managing package.json dependencies within schematics, including adding, removing, and modifying npm packages with automatic installation handling.
3
4
## Capabilities
5
6
### Adding Dependencies
7
8
Primary function for adding npm packages to a project's package.json.
9
10
```typescript { .api }
11
/**
12
* Adds a package dependency to package.json and optionally schedules installation
13
* @param options - Dependency configuration options
14
* @returns Rule that adds the dependency
15
*/
16
function addDependency(options: AddDependencyOptions): Rule;
17
18
interface AddDependencyOptions {
19
/** Dependency type (dependencies, devDependencies, peerDependencies) */
20
type: DependencyType;
21
/** Package name */
22
name: string;
23
/** Package version */
24
version: string;
25
/** Optional npm registry URL */
26
registry?: string;
27
/** Installation behavior (None, Auto, Always) */
28
installBehavior?: InstallBehavior;
29
/** Behavior when dependency already exists */
30
existingBehavior?: ExistingBehavior;
31
/** Target project name */
32
project?: string;
33
}
34
35
enum DependencyType {
36
Default = 'dependencies',
37
Dev = 'devDependencies',
38
Peer = 'peerDependencies'
39
}
40
41
enum InstallBehavior {
42
/** Do not schedule npm install */
43
None,
44
/** Automatically determine if install is needed */
45
Auto,
46
/** Always schedule npm install */
47
Always
48
}
49
50
enum ExistingBehavior {
51
/** Skip if dependency already exists */
52
Skip,
53
/** Replace existing dependency version */
54
Replace
55
}
56
```
57
58
**Usage Examples:**
59
60
```typescript
61
import { addDependency, DependencyType, InstallBehavior } from '@schematics/angular/utility';
62
63
// Add runtime dependency
64
export function addAngularMaterial(): Rule {
65
return addDependency({
66
type: DependencyType.Default,
67
name: '@angular/material',
68
version: '^15.0.0',
69
installBehavior: InstallBehavior.Always
70
});
71
}
72
73
// Add development dependency
74
export function addTestingLibrary(): Rule {
75
return addDependency({
76
type: DependencyType.Dev,
77
name: '@testing-library/angular',
78
version: '^13.0.0',
79
existingBehavior: ExistingBehavior.Replace,
80
installBehavior: InstallBehavior.Auto
81
});
82
}
83
84
// Add peer dependency
85
export function addPeerDep(): Rule {
86
return addDependency({
87
type: DependencyType.Peer,
88
name: 'rxjs',
89
version: '^7.5.0',
90
installBehavior: InstallBehavior.None
91
});
92
}
93
```
94
95
### Package.json Manipulation
96
97
Low-level functions for directly manipulating package.json files.
98
99
```typescript { .api }
100
/**
101
* Adds a dependency directly to package.json without installation
102
* @param tree - Virtual file system tree
103
* @param dependency - Dependency to add
104
* @param pkgJsonPath - Optional path to package.json (defaults to '/package.json')
105
*/
106
function addPackageJsonDependency(
107
tree: Tree,
108
dependency: NodeDependency,
109
pkgJsonPath?: string
110
): void;
111
112
/**
113
* Retrieves a dependency from package.json
114
* @param tree - Virtual file system tree
115
* @param name - Package name to retrieve
116
* @param pkgJsonPath - Optional path to package.json
117
* @returns Dependency object or null if not found
118
*/
119
function getPackageJsonDependency(
120
tree: Tree,
121
name: string,
122
pkgJsonPath?: string
123
): NodeDependency | null;
124
125
/**
126
* Removes a dependency from package.json
127
* @param tree - Virtual file system tree
128
* @param name - Package name to remove
129
* @param pkgJsonPath - Optional path to package.json
130
*/
131
function removePackageJsonDependency(
132
tree: Tree,
133
name: string,
134
pkgJsonPath?: string
135
): void;
136
137
interface NodeDependency {
138
/** Package name */
139
name: string;
140
/** Package version */
141
version: string;
142
/** Dependency type */
143
type: NodeDependencyType;
144
/** Whether dependency was overwritten */
145
overwrite?: boolean;
146
}
147
148
enum NodeDependencyType {
149
Default = 'dependencies',
150
Dev = 'devDependencies',
151
Peer = 'peerDependencies',
152
Optional = 'optionalDependencies'
153
}
154
```
155
156
**Usage Example:**
157
158
```typescript
159
import {
160
addPackageJsonDependency,
161
getPackageJsonDependency,
162
NodeDependencyType
163
} from '@schematics/angular/utility';
164
165
export function managePackages(): Rule {
166
return (tree: Tree) => {
167
// Check if package exists
168
const existing = getPackageJsonDependency(tree, '@angular/core');
169
170
if (!existing) {
171
// Add package directly
172
addPackageJsonDependency(tree, {
173
name: '@angular/core',
174
version: '^15.0.0',
175
type: NodeDependencyType.Default
176
});
177
}
178
179
return tree;
180
};
181
}
182
```
183
184
### Version Management
185
186
Utilities for managing package versions and latest version information.
187
188
```typescript { .api }
189
/**
190
* Object containing latest stable versions of Angular packages
191
* Updated with each release of @schematics/angular
192
*/
193
declare const latestVersions: {
194
/** Latest Angular framework version */
195
Angular: string;
196
/** Latest Angular DevKit Build Angular version */
197
DevkitBuildAngular: string;
198
/** Latest Angular DevKit Schematics version */
199
DevkitSchematics: string;
200
/** Latest Angular CLI version */
201
AngularCli: string;
202
/** Latest RxJS version */
203
RxJs: string;
204
/** Latest TypeScript version */
205
TypeScript: string;
206
/** Latest Zone.js version */
207
ZoneJs: string;
208
/** Latest Angular PWA version */
209
AngularPWA: string;
210
/** Additional package versions */
211
[packageName: string]: string;
212
};
213
```
214
215
**Usage Example:**
216
217
```typescript
218
import { addDependency, latestVersions, DependencyType } from '@schematics/angular/utility';
219
220
export function addLatestAngular(): Rule {
221
return addDependency({
222
type: DependencyType.Default,
223
name: '@angular/core',
224
version: latestVersions.Angular // Uses latest stable version
225
});
226
}
227
```
228
229
### Installation Tasks
230
231
Functions for scheduling npm/yarn installation tasks after dependency changes.
232
233
```typescript { .api }
234
/**
235
* Schedules a package installation task
236
* Note: This is handled automatically by addDependency when installBehavior is set
237
* @param context - Schematic context
238
* @param packageManager - Package manager to use ('npm' | 'yarn' | 'pnpm')
239
* @returns Task ID
240
*/
241
function schedulePackageInstall(
242
context: SchematicContext,
243
packageManager?: string
244
): TaskId;
245
```
246
247
### Additional Dependency Utilities
248
249
Extended dependency management functions available via direct import.
250
251
```typescript { .api }
252
// Import from @schematics/angular/utility/dependencies
253
import {
254
addPackageJsonDependency,
255
getPackageJsonDependency,
256
removePackageJsonDependency,
257
NodeDependency,
258
NodeDependencyType
259
} from '@schematics/angular/utility/dependencies';
260
261
/**
262
* Adds a dependency directly to package.json without installation
263
* @param tree - Virtual file system tree
264
* @param dependency - Dependency to add
265
* @param pkgJsonPath - Optional path to package.json (defaults to '/package.json')
266
*/
267
function addPackageJsonDependency(
268
tree: Tree,
269
dependency: NodeDependency,
270
pkgJsonPath?: string
271
): void;
272
273
/**
274
* Retrieves a dependency from package.json
275
* @param tree - Virtual file system tree
276
* @param name - Package name to retrieve
277
* @param pkgJsonPath - Optional path to package.json
278
* @returns Dependency object or null if not found
279
*/
280
function getPackageJsonDependency(
281
tree: Tree,
282
name: string,
283
pkgJsonPath?: string
284
): NodeDependency | null;
285
286
/**
287
* Removes a dependency from package.json
288
* @param tree - Virtual file system tree
289
* @param name - Package name to remove
290
* @param pkgJsonPath - Optional path to package.json
291
*/
292
function removePackageJsonDependency(
293
tree: Tree,
294
name: string,
295
pkgJsonPath?: string
296
): void;
297
298
interface NodeDependency {
299
/** Package name */
300
name: string;
301
/** Package version */
302
version: string;
303
/** Dependency type */
304
type: NodeDependencyType;
305
/** Whether dependency was overwritten */
306
overwrite?: boolean;
307
}
308
309
enum NodeDependencyType {
310
Default = 'dependencies',
311
Dev = 'devDependencies',
312
Peer = 'peerDependencies',
313
Optional = 'optionalDependencies'
314
}
315
```
316
317
## Advanced Usage
318
319
### Conditional Dependencies
320
321
```typescript
322
import { addDependency, DependencyType, ExistingBehavior } from '@schematics/angular/utility';
323
324
export function conditionalDependencies(): Rule {
325
return async (tree: Tree, context: SchematicContext) => {
326
// Check Angular version before adding dependency
327
const packageJson = tree.readText('/package.json');
328
const pkg = JSON.parse(packageJson);
329
const angularVersion = pkg.dependencies?.['@angular/core'];
330
331
if (angularVersion && angularVersion.includes('15')) {
332
return addDependency({
333
type: DependencyType.Default,
334
name: '@angular/material',
335
version: '^15.0.0',
336
existingBehavior: ExistingBehavior.Replace
337
});
338
}
339
340
return noop();
341
};
342
}
343
```
344
345
### Multiple Dependencies
346
347
```typescript
348
import { chain } from '@angular-devkit/schematics';
349
import { addDependency, DependencyType } from '@schematics/angular/utility';
350
351
export function addMultipleDependencies(): Rule {
352
return chain([
353
addDependency({
354
type: DependencyType.Default,
355
name: '@angular/material',
356
version: '^15.0.0'
357
}),
358
addDependency({
359
type: DependencyType.Default,
360
name: '@angular/cdk',
361
version: '^15.0.0'
362
}),
363
addDependency({
364
type: DependencyType.Dev,
365
name: '@angular/material-moment-adapter',
366
version: '^15.0.0'
367
})
368
]);
369
}
370
```
371
372
### Custom Registry
373
374
```typescript
375
export function addFromPrivateRegistry(): Rule {
376
return addDependency({
377
type: DependencyType.Default,
378
name: '@company/shared-lib',
379
version: '^1.0.0',
380
registry: 'https://npm.company.com/',
381
installBehavior: InstallBehavior.Always
382
});
383
}
384
```