0
# Package Management
1
2
Tools for detecting package managers, managing dependencies, and handling package.json operations. These utilities provide consistent package management across different tools (npm, yarn, pnpm, bun) and enable automated dependency management in generators and executors.
3
4
## Capabilities
5
6
### Package Manager Detection
7
8
Functions for detecting and working with different package managers.
9
10
```typescript { .api }
11
/**
12
* Supported package managers
13
*/
14
type PackageManager = 'npm' | 'yarn' | 'pnpm' | 'bun';
15
16
/**
17
* Detect which package manager is being used in a directory
18
* @param dir - Directory to check (defaults to current working directory)
19
* @returns Detected package manager
20
*/
21
function detectPackageManager(dir?: string): PackageManager;
22
23
/**
24
* Get command-line commands for the detected package manager
25
* @param packageManager - Package manager to get commands for
26
* @returns Object with common commands for the package manager
27
*/
28
function getPackageManagerCommand(
29
packageManager?: PackageManager
30
): {
31
install: string;
32
add: string;
33
addDev: string;
34
rm: string;
35
exec: string;
36
dlx: string;
37
list: string;
38
};
39
40
/**
41
* Get the version of the package manager
42
* @param packageManager - Package manager to check
43
* @returns Version string
44
*/
45
function getPackageManagerVersion(packageManager: PackageManager): string;
46
47
/**
48
* Check if workspaces are enabled for the package manager
49
* @param packageManager - Package manager to check
50
* @param root - Workspace root directory
51
* @returns Whether workspaces are enabled
52
*/
53
function isWorkspacesEnabled(
54
packageManager: PackageManager,
55
root: string
56
): boolean;
57
```
58
59
**Usage Examples:**
60
61
```typescript
62
import {
63
detectPackageManager,
64
getPackageManagerCommand,
65
getPackageManagerVersion
66
} from "@nrwl/devkit";
67
68
function handlePackageManager() {
69
// Detect package manager
70
const pm = detectPackageManager();
71
console.log('Using package manager:', pm);
72
73
// Get commands for the detected package manager
74
const commands = getPackageManagerCommand(pm);
75
console.log('Install command:', commands.install);
76
console.log('Add dependency command:', commands.add);
77
78
// Get version
79
const version = getPackageManagerVersion(pm);
80
console.log(`${pm} version:`, version);
81
82
// Example usage of commands
83
if (pm === 'yarn') {
84
console.log('Add dev dependency:', `${commands.addDev} jest`);
85
} else if (pm === 'pnpm') {
86
console.log('Execute command:', `${commands.exec} nx build`);
87
}
88
}
89
```
90
91
### Package.json Management
92
93
Functions for managing dependencies in package.json files.
94
95
```typescript { .api }
96
/**
97
* Add dependencies to package.json
98
* @param tree - Virtual file system tree
99
* @param dependencies - Production dependencies to add
100
* @param devDependencies - Development dependencies to add
101
* @param packageJsonPath - Path to package.json (defaults to root)
102
* @returns Generator callback to install packages
103
*/
104
function addDependenciesToPackageJson(
105
tree: Tree,
106
dependencies: Record<string, string>,
107
devDependencies: Record<string, string>,
108
packageJsonPath?: string
109
): GeneratorCallback;
110
111
/**
112
* Remove dependencies from package.json
113
* @param tree - Virtual file system tree
114
* @param dependencies - Production dependencies to remove
115
* @param devDependencies - Development dependencies to remove
116
* @param packageJsonPath - Path to package.json (defaults to root)
117
* @returns Generator callback to clean up node_modules if needed
118
*/
119
function removeDependenciesFromPackageJson(
120
tree: Tree,
121
dependencies: string[],
122
devDependencies: string[],
123
packageJsonPath?: string
124
): GeneratorCallback;
125
126
/**
127
* Ensure a package is available, installing it if necessary
128
* @template T - Expected package export type
129
* @param packageName - Name of the package to ensure
130
* @param version - Version to install if not present
131
* @returns The package's exports
132
*/
133
function ensurePackage<T = any>(packageName: string, version: string): T;
134
```
135
136
**Usage Examples:**
137
138
```typescript
139
import {
140
Tree,
141
addDependenciesToPackageJson,
142
removeDependenciesFromPackageJson,
143
ensurePackage,
144
GeneratorCallback
145
} from "@nrwl/devkit";
146
147
function manageDependencies(tree: Tree): GeneratorCallback {
148
// Add dependencies to the main package.json
149
const installTask = addDependenciesToPackageJson(
150
tree,
151
{
152
// Production dependencies
153
'lodash': '^4.17.21',
154
'axios': '^1.0.0'
155
},
156
{
157
// Development dependencies
158
'@types/lodash': '^4.14.0',
159
'jest': '^29.0.0'
160
}
161
);
162
163
// Add dependencies to a specific package.json
164
const libInstallTask = addDependenciesToPackageJson(
165
tree,
166
{ 'date-fns': '^2.29.0' },
167
{ '@types/date-fns': '^2.6.0' },
168
'libs/my-lib/package.json'
169
);
170
171
// Remove outdated dependencies
172
const removeTask = removeDependenciesFromPackageJson(
173
tree,
174
['moment'], // Remove from dependencies
175
['@types/moment'], // Remove from devDependencies
176
);
177
178
// Return combined callback
179
return async () => {
180
await installTask();
181
await libInstallTask();
182
await removeTask();
183
};
184
}
185
186
function useEnsurePackage() {
187
// Dynamically ensure a package is available
188
try {
189
const chalk = ensurePackage('chalk', '^4.1.0');
190
console.log(chalk.blue('Package is now available!'));
191
} catch (error) {
192
console.error('Failed to ensure package:', error);
193
}
194
}
195
```
196
197
### Package Installation Tasks
198
199
Functions for creating installation tasks that run after file generation.
200
201
```typescript { .api }
202
/**
203
* Create a task to install packages
204
* @param options - Installation options
205
* @returns Generator callback that installs packages
206
*/
207
function installPackagesTask(options?: {
208
/** Package manager to use */
209
packageManager?: PackageManager;
210
/** Working directory */
211
cwd?: string;
212
/** Whether to install in quiet mode */
213
quiet?: boolean;
214
}): GeneratorCallback;
215
```
216
217
**Usage Examples:**
218
219
```typescript
220
import {
221
Tree,
222
installPackagesTask,
223
detectPackageManager,
224
GeneratorCallback
225
} from "@nrwl/devkit";
226
227
export default async function myGenerator(tree: Tree, options: any) {
228
// Generate files and modify package.json
229
// ... file generation code ...
230
231
// Create installation task
232
const installTask = installPackagesTask({
233
packageManager: detectPackageManager(),
234
quiet: false
235
});
236
237
// Return the task to be executed after file changes are applied
238
return installTask;
239
}
240
```
241
242
### Version Constants
243
244
Constants for version management and compatibility.
245
246
```typescript { .api }
247
/**
248
* Current Nx version being used
249
*/
250
const NX_VERSION: string;
251
```
252
253
**Usage Examples:**
254
255
```typescript
256
import { NX_VERSION, addDependenciesToPackageJson } from "@nrwl/devkit";
257
258
function addNxDependencies(tree: Tree) {
259
// Add Nx dependencies with the current version
260
return addDependenciesToPackageJson(
261
tree,
262
{},
263
{
264
'@nx/workspace': NX_VERSION,
265
'@nx/jest': NX_VERSION,
266
'@nx/eslint-plugin': NX_VERSION
267
}
268
);
269
}
270
```
271
272
### Advanced Package Management
273
274
Utilities for more complex package management scenarios.
275
276
```typescript { .api }
277
/**
278
* Get workspace package.json
279
* @param tree - Virtual file system tree
280
* @returns Workspace package.json content
281
*/
282
function getWorkspacePackageJson(tree: Tree): {
283
name?: string;
284
version?: string;
285
dependencies?: Record<string, string>;
286
devDependencies?: Record<string, string>;
287
workspaces?: string[] | { packages: string[] };
288
};
289
290
/**
291
* Update workspace package.json
292
* @param tree - Virtual file system tree
293
* @param updater - Function to update package.json
294
*/
295
function updateWorkspacePackageJson(
296
tree: Tree,
297
updater: (packageJson: any) => any
298
): void;
299
300
/**
301
* Check if a package is installed
302
* @param packageName - Name of package to check
303
* @param tree - Virtual file system tree (optional)
304
* @returns Whether package is installed
305
*/
306
function isPackageInstalled(packageName: string, tree?: Tree): boolean;
307
308
/**
309
* Get installed package version
310
* @param packageName - Name of package to check
311
* @param tree - Virtual file system tree (optional)
312
* @returns Installed version or null if not installed
313
*/
314
function getInstalledPackageVersion(
315
packageName: string,
316
tree?: Tree
317
): string | null;
318
```
319
320
**Usage Examples:**
321
322
```typescript
323
import {
324
Tree,
325
getWorkspacePackageJson,
326
updateWorkspacePackageJson,
327
isPackageInstalled,
328
getInstalledPackageVersion
329
} from "@nrwl/devkit";
330
331
function advancedPackageManagement(tree: Tree) {
332
// Get workspace package.json
333
const workspacePackageJson = getWorkspacePackageJson(tree);
334
console.log('Workspace name:', workspacePackageJson.name);
335
336
// Update workspace package.json
337
updateWorkspacePackageJson(tree, (packageJson) => {
338
return {
339
...packageJson,
340
scripts: {
341
...packageJson.scripts,
342
'build:all': 'nx run-many --target=build --all'
343
}
344
};
345
});
346
347
// Check if packages are installed
348
if (isPackageInstalled('react', tree)) {
349
const reactVersion = getInstalledPackageVersion('react', tree);
350
console.log('React version:', reactVersion);
351
}
352
353
// Conditional dependency management
354
if (!isPackageInstalled('@nx/react', tree)) {
355
console.log('React plugin not installed');
356
}
357
}
358
```