0
# Package Management
1
2
@nx/js provides comprehensive package.json management utilities for creating, updating, and maintaining package manifests with support for exports fields, entry points, dependency management, and build artifact integration.
3
4
## Capabilities
5
6
### Package.json Creation
7
8
Creates package.json files with dependency resolution, exports field generation, and Nx-specific optimizations.
9
10
```typescript { .api }
11
/**
12
* Creates package.json for a project with dependency resolution
13
* @param projectName - Name of the project
14
* @param graph - Project dependency graph
15
* @param options - Package.json creation options
16
* @returns Generated package.json object
17
*/
18
function createPackageJson(
19
projectName: string,
20
graph: ProjectGraph,
21
options: CreatePackageJsonOptions
22
): PackageJson;
23
24
interface CreatePackageJsonOptions {
25
target?: string; // Target name for the build
26
root?: string; // Workspace root directory
27
isProduction?: boolean; // Include only production dependencies
28
helperDependencies?: string[]; // Additional helper dependencies to include
29
}
30
```
31
32
**Usage Example:**
33
34
```typescript
35
import { createPackageJson } from "@nx/js";
36
37
const packageJson = createPackageJson('my-lib', projectGraph, {
38
target: 'build',
39
isProduction: true,
40
helperDependencies: ['tslib']
41
});
42
```
43
44
### Package.json Updates
45
46
Updates existing package.json files with build artifacts, exports fields, and dependency information.
47
48
```typescript { .api }
49
/**
50
* Updates package.json with build artifacts and dependency information
51
* @param options - Update configuration options
52
* @param context - Nx executor context
53
* @param target - Target project node
54
* @param dependencies - Array of dependent buildable project nodes
55
* @param fileMap - Optional project file map for additional context
56
*/
57
function updatePackageJson(
58
options: UpdatePackageJsonOption,
59
context: ExecutorContext,
60
target: ProjectGraphProjectNode,
61
dependencies: DependentBuildableProjectNode[],
62
fileMap?: ProjectFileMap
63
): void;
64
65
/**
66
* Gets updated package.json content without writing to file system
67
* @param packageJson - Original package.json object
68
* @param options - Update configuration options
69
* @returns Updated package.json object
70
*/
71
function getUpdatedPackageJsonContent(
72
packageJson: PackageJson,
73
options: UpdatePackageJsonOption
74
): PackageJson;
75
76
interface UpdatePackageJsonOption {
77
outputPath: string; // Build output directory
78
main?: string; // Main entry file path
79
generateExportsField?: boolean; // Generate exports field
80
additionalEntryPoints?: string[]; // Additional entry points for exports
81
format?: SupportedFormat[]; // Output formats (cjs, esm)
82
skipTypings?: boolean; // Skip generating typings field
83
generateLockfile?: boolean; // Generate matching lockfile
84
updateBuildableProjectDepsInPackageJson?: boolean; // Update buildable project dependencies
85
buildableProjectDepsInPackageJsonType?: DependencyType; // Dependency type for buildable projects
86
}
87
88
type SupportedFormat = 'cjs' | 'esm';
89
type DependencyType = 'dependencies' | 'devDependencies' | 'peerDependencies';
90
```
91
92
**Usage Examples:**
93
94
```typescript
95
import { updatePackageJson, getUpdatedPackageJsonContent } from "@nx/js";
96
97
// Update package.json in place
98
updatePackageJson({
99
outputPath: 'dist/libs/my-lib',
100
main: './src/index.js',
101
generateExportsField: true,
102
additionalEntryPoints: ['./src/utils.js'],
103
format: ['cjs', 'esm']
104
}, context, target, dependencies);
105
106
// Get updated content without writing
107
const originalPackageJson = { name: 'my-lib', version: '1.0.0' };
108
const updatedPackageJson = getUpdatedPackageJsonContent(originalPackageJson, {
109
outputPath: 'dist/libs/my-lib',
110
main: './src/index.js',
111
generateExportsField: true
112
});
113
```
114
115
### Exports Field Generation
116
117
Generates modern package.json exports fields for multi-format packages with conditional exports.
118
119
```typescript { .api }
120
/**
121
* Generates exports field for package.json
122
* @param options - Options containing output path, main file, and entry points
123
* @returns Exports field object for package.json
124
*/
125
function getExports(options: Pick<
126
UpdatePackageJsonOption,
127
'outputPath' | 'main' | 'additionalEntryPoints' | 'generateExportsField' | 'format'
128
>): Exports;
129
130
interface Exports {
131
[key: string]: string | ExportConditions;
132
}
133
134
interface ExportConditions {
135
types?: string; // TypeScript declaration file
136
import?: string; // ESM import path
137
require?: string; // CommonJS require path
138
default?: string; // Default fallback path
139
}
140
```
141
142
**Usage Example:**
143
144
```typescript
145
import { getExports } from "@nx/js";
146
147
const exports = getExports({
148
outputPath: 'dist/libs/my-lib',
149
main: './src/index.js',
150
additionalEntryPoints: ['./src/utils.js', './src/helpers.js'],
151
generateExportsField: true,
152
format: ['cjs', 'esm']
153
});
154
155
// Results in exports like:
156
// {
157
// ".": {
158
// "types": "./index.d.ts",
159
// "import": "./index.esm.js",
160
// "require": "./index.cjs.js",
161
// "default": "./index.js"
162
// },
163
// "./utils": {
164
// "types": "./utils.d.ts",
165
// "import": "./utils.esm.js",
166
// "require": "./utils.cjs.js"
167
// }
168
// }
169
```
170
171
### Entry Points Creation
172
173
Creates additional entry points for libraries with multiple export paths.
174
175
```typescript { .api }
176
/**
177
* Creates entry points from additional entry points configuration
178
* @param additionalEntryPoints - Array of additional entry point paths or undefined
179
* @param root - Project root directory
180
* @returns Array of matched entry point file paths
181
*/
182
function createEntryPoints(
183
additionalEntryPoints: undefined | string[],
184
root: string
185
): string[];
186
```
187
188
**Usage Example:**
189
190
```typescript
191
import { createEntryPoints } from "@nx/js";
192
193
const entryPoints = createEntryPoints([
194
'src/utils/*',
195
'src/helpers/index.ts'
196
], 'libs/my-lib');
197
198
// Returns resolved file paths like:
199
// ['src/utils/string-utils.ts', 'src/utils/date-utils.ts', 'src/helpers/index.ts']
200
```
201
202
### Output Directory Resolution
203
204
Resolves output directories for build artifacts and package placement.
205
206
```typescript { .api }
207
/**
208
* Gets the output directory for build artifacts
209
* @param options - Options containing output path configuration
210
* @returns Resolved output directory path
211
*/
212
function getOutputDir(options: Pick<UpdatePackageJsonOption, 'outputPath'>): string;
213
```
214
215
**Usage Example:**
216
217
```typescript
218
import { getOutputDir } from "@nx/js";
219
220
const outputDir = getOutputDir({
221
outputPath: 'dist/libs/my-lib'
222
});
223
// Returns: 'dist/libs/my-lib'
224
```
225
226
### Package.json Copying
227
228
Copies and updates package.json files as part of the build process with dependency resolution.
229
230
```typescript { .api }
231
/**
232
* Copies package.json to output directory with updates
233
* @param options - Copy configuration options
234
* @param context - Nx executor context
235
* @returns Promise resolving to copy result with success status
236
*/
237
function copyPackageJson(
238
options: CopyPackageJsonOptions,
239
context: ExecutorContext
240
): Promise<CopyPackageJsonResult>;
241
242
interface CopyPackageJsonOptions extends UpdatePackageJsonOption {
243
// Inherits all UpdatePackageJsonOption properties
244
}
245
246
interface CopyPackageJsonResult {
247
success: boolean; // Whether copy operation succeeded
248
stop?(): void; // Optional cleanup function
249
}
250
```
251
252
**Usage Example:**
253
254
```typescript
255
import { copyPackageJson } from "@nx/js";
256
257
const result = await copyPackageJson({
258
outputPath: 'dist/libs/my-lib',
259
main: './src/index.js',
260
generateExportsField: true,
261
generateLockfile: true
262
}, context);
263
264
if (result.success) {
265
console.log('Package.json copied successfully');
266
}
267
268
// Cleanup if needed
269
if (result.stop) {
270
result.stop();
271
}
272
```
273
274
### Lockfile Management
275
276
Creates lockfiles that match the workspace configuration for consistent dependency versions.
277
278
```typescript { .api }
279
/**
280
* Creates lockfile matching workspace dependency versions
281
* @param packageJson - Package.json object to create lockfile for
282
* @param packageJsonPath - Path to package.json file
283
* @param options - Lockfile creation options
284
* @returns Promise resolving when lockfile is created
285
*/
286
function createLockFile(
287
packageJson: PackageJson,
288
packageJsonPath: string,
289
options?: CreateLockFileOptions
290
): Promise<void>;
291
292
/**
293
* Gets appropriate lockfile name for the current package manager
294
* @param packageManager - Package manager type
295
* @returns Lockfile filename (package-lock.json, yarn.lock, etc.)
296
*/
297
function getLockFileName(packageManager?: PackageManagerType): string;
298
299
interface CreateLockFileOptions {
300
packageManager?: PackageManagerType; // Package manager to use
301
skipInstall?: boolean; // Skip installing dependencies
302
}
303
304
type PackageManagerType = 'npm' | 'yarn' | 'pnpm' | 'bun';
305
```
306
307
**Usage Example:**
308
309
```typescript
310
import { createLockFile, getLockFileName } from "@nx/js";
311
312
// Create lockfile for npm
313
await createLockFile(
314
packageJson,
315
'dist/libs/my-lib/package.json',
316
{ packageManager: 'npm' }
317
);
318
319
// Get lockfile name
320
const lockfileName = getLockFileName('npm');
321
// Returns: 'package-lock.json'
322
```
323
324
## Common Types
325
326
```typescript { .api }
327
interface PackageJson {
328
name: string; // Package name
329
version: string; // Package version
330
description?: string; // Package description
331
main?: string; // Main entry point
332
module?: string; // ESM entry point
333
types?: string; // TypeScript declarations
334
exports?: Exports; // Modern exports field
335
scripts?: Record<string, string>; // npm scripts
336
dependencies?: Record<string, string>; // Runtime dependencies
337
devDependencies?: Record<string, string>; // Development dependencies
338
peerDependencies?: Record<string, string>; // Peer dependencies
339
[key: string]: any; // Additional fields
340
}
341
342
interface ProjectGraphProjectNode {
343
name: string; // Project name
344
type: string; // Project type
345
data: {
346
root: string; // Project root directory
347
sourceRoot?: string; // Source root directory
348
targets?: Record<string, any>; // Project targets
349
[key: string]: any; // Additional project data
350
};
351
}
352
353
interface DependentBuildableProjectNode {
354
name: string; // Project name
355
outputs: string[]; // Build output paths
356
node: ProjectGraphProjectNode; // Project graph node
357
}
358
```
359
360
## Package Management Patterns
361
362
### Multi-Format Packages
363
364
Create packages that support both CommonJS and ESM:
365
366
```typescript
367
const exports = getExports({
368
outputPath: 'dist/libs/my-lib',
369
main: './src/index.js',
370
format: ['cjs', 'esm'],
371
generateExportsField: true
372
});
373
374
// Generates conditional exports for both formats
375
```
376
377
### Entry Point Organization
378
379
Structure packages with multiple entry points:
380
381
```typescript
382
const updatedPackageJson = getUpdatedPackageJsonContent(originalPackageJson, {
383
outputPath: 'dist/libs/ui-components',
384
main: './src/index.js',
385
additionalEntryPoints: [
386
'./src/buttons/index.js',
387
'./src/forms/index.js',
388
'./src/layouts/index.js'
389
],
390
generateExportsField: true
391
});
392
393
// Allows imports like:
394
// import { Button } from '@myorg/ui-components/buttons';
395
// import { Form } from '@myorg/ui-components/forms';
396
```
397
398
### Dependency Management
399
400
Control which dependencies are included in built packages:
401
402
```typescript
403
updatePackageJson({
404
outputPath: 'dist/libs/my-lib',
405
updateBuildableProjectDepsInPackageJson: true,
406
buildableProjectDepsInPackageJsonType: 'dependencies'
407
}, context, target, dependencies);
408
```
409
410
### Development vs Production
411
412
Create different package.json files for different environments:
413
414
```typescript
415
// Production package.json
416
const prodPackageJson = createPackageJson('my-lib', graph, {
417
isProduction: true
418
});
419
420
// Development package.json with all dependencies
421
const devPackageJson = createPackageJson('my-lib', graph, {
422
isProduction: false
423
});
424
```