0
# Lockfile Management
1
2
The Shrinkwrap class manages package-lock.json and npm-shrinkwrap.json files, providing support for multiple lockfile versions with bidirectional conversion and metadata preservation.
3
4
## Capabilities
5
6
### Constructor
7
8
Creates a new Shrinkwrap instance for managing lockfiles.
9
10
```javascript { .api }
11
/**
12
* Create a new Shrinkwrap instance
13
* @param options - Shrinkwrap configuration options
14
*/
15
constructor(options?: ShrinkwrapOptions): Shrinkwrap;
16
17
interface ShrinkwrapOptions {
18
/** Project path, defaults to current directory */
19
path?: string;
20
/** Lockfile version (1, 2, or 3) */
21
lockfileVersion?: 1 | 2 | 3;
22
/** JSON indentation, default 2 */
23
indent?: number;
24
/** Line ending character, default '\n' */
25
newline?: string;
26
/** Only use npm-shrinkwrap.json, default false */
27
shrinkwrapOnly?: boolean;
28
/** Hidden lockfile, default false */
29
hiddenLockfile?: boolean;
30
/** Resolve options */
31
resolveOptions?: object;
32
}
33
```
34
35
**Usage Example:**
36
37
```javascript
38
const { Shrinkwrap } = require('@npmcli/arborist');
39
40
// Create with default options
41
const shrinkwrap = new Shrinkwrap({
42
path: '/path/to/project',
43
lockfileVersion: 3
44
});
45
```
46
47
### Static Methods
48
49
Factory methods for loading and creating Shrinkwrap instances.
50
51
```javascript { .api }
52
/**
53
* Load shrinkwrap from disk
54
* @param options - Loading options
55
* @returns Promise resolving to Shrinkwrap instance
56
*/
57
static load(options?: ShrinkwrapOptions): Promise<Shrinkwrap>;
58
59
/**
60
* Create new shrinkwrap (reset existing)
61
* @param options - Creation options
62
* @returns Promise resolving to new Shrinkwrap instance
63
*/
64
static reset(options?: ShrinkwrapOptions): Promise<Shrinkwrap>;
65
66
/**
67
* Extract metadata from a node for lockfile storage
68
* @param node - Node to extract metadata from
69
* @param path - Path for metadata storage
70
* @param options - Extraction options
71
* @returns Metadata object
72
*/
73
static metaFromNode(node: Node, path: string, options?: object): object;
74
```
75
76
**Usage Examples:**
77
78
```javascript
79
// Load existing lockfile
80
const shrinkwrap = await Shrinkwrap.load({
81
path: '/path/to/project'
82
});
83
84
// Create new lockfile
85
const newShrinkwrap = await Shrinkwrap.reset({
86
path: '/path/to/project',
87
lockfileVersion: 3
88
});
89
90
// Extract metadata from node
91
const metadata = Shrinkwrap.metaFromNode(node, 'node_modules/package');
92
```
93
94
### Static Properties
95
96
Static properties available on the Shrinkwrap class.
97
98
```javascript { .api }
99
interface ShrinkwrapStatics {
100
/** Default lockfile version */
101
static defaultLockfileVersion: 3;
102
/** Key ordering for JSON serialization */
103
static keyOrder: string[];
104
}
105
```
106
107
### Configuration Properties
108
109
Properties defining the shrinkwrap configuration and behavior.
110
111
```javascript { .api }
112
interface ShrinkwrapConfiguration {
113
/** Project path */
114
path: string;
115
/** Lockfile filename (package-lock.json or npm-shrinkwrap.json) */
116
filename: string;
117
/** Current lockfile version */
118
lockfileVersion: number;
119
/** Original version when loaded from disk */
120
originalLockfileVersion: number;
121
/** JSON indentation */
122
indent: number;
123
/** Line ending character */
124
newline: string;
125
/** Filename type */
126
type: string;
127
}
128
```
129
130
**Usage Example:**
131
132
```javascript
133
console.log(`Lockfile: ${shrinkwrap.filename}`);
134
console.log(`Version: ${shrinkwrap.lockfileVersion}`);
135
console.log(`Original version: ${shrinkwrap.originalLockfileVersion}`);
136
```
137
138
### State Properties
139
140
Properties indicating the current state and content of the shrinkwrap.
141
142
```javascript { .api }
143
interface ShrinkwrapState {
144
/** Lockfile data object */
145
data: object;
146
/** Associated tree */
147
tree: Node | null;
148
/** Was loaded from existing file */
149
loadedFromDisk: boolean;
150
/** Is hidden lockfile */
151
hiddenLockfile: boolean;
152
/** Only npm-shrinkwrap.json */
153
shrinkwrapOnly: boolean;
154
/** Loading error if any */
155
loadingError: Error | null;
156
/** Yarn lock data */
157
yarnLock: any | null;
158
/** Is ancient lockfile format */
159
ancientLockfile: boolean;
160
/** Resolve options */
161
resolveOptions: object;
162
}
163
```
164
165
**Usage Example:**
166
167
```javascript
168
// Check shrinkwrap state
169
if (shrinkwrap.loadedFromDisk) {
170
console.log('Loaded existing lockfile');
171
} else {
172
console.log('Created new lockfile');
173
}
174
175
if (shrinkwrap.loadingError) {
176
console.error('Loading error:', shrinkwrap.loadingError.message);
177
}
178
179
// Access lockfile data
180
console.log('Lockfile data:', shrinkwrap.data);
181
```
182
183
### File Operations
184
185
Methods for loading from and saving to disk.
186
187
```javascript { .api }
188
/**
189
* Load shrinkwrap data from disk
190
* @returns Promise that resolves when loading is complete
191
*/
192
async load(): Promise<void>;
193
194
/**
195
* Save shrinkwrap data to disk
196
* @param options - Save options
197
* @returns Promise that resolves when saving is complete
198
*/
199
async save(options?: SaveOptions): Promise<void>;
200
201
/**
202
* Reset to empty state
203
*/
204
reset(): void;
205
206
/**
207
* Commit pending changes
208
*/
209
commit(): void;
210
211
interface SaveOptions {
212
/** Format the JSON output */
213
format?: boolean;
214
}
215
```
216
217
**Usage Examples:**
218
219
```javascript
220
// Load from disk
221
await shrinkwrap.load();
222
223
// Save to disk
224
await shrinkwrap.save();
225
226
// Save with formatting
227
await shrinkwrap.save({ format: true });
228
229
// Reset to empty state
230
shrinkwrap.reset();
231
232
// Commit pending changes
233
shrinkwrap.commit();
234
```
235
236
### Data Access
237
238
Methods for accessing and modifying lockfile data.
239
240
```javascript { .api }
241
/**
242
* Get node metadata by path
243
* @param nodePath - Path to node in lockfile
244
* @returns Metadata object or undefined
245
*/
246
get(nodePath: string): any;
247
248
/**
249
* Delete node metadata by path
250
* @param nodePath - Path to node in lockfile
251
*/
252
delete(nodePath: string): void;
253
254
/**
255
* Add node to shrinkwrap
256
* @param node - Node to add
257
*/
258
add(node: Node): void;
259
260
/**
261
* Add edge metadata to shrinkwrap
262
* @param edge - Edge to add metadata for
263
*/
264
addEdge(edge: Edge): void;
265
```
266
267
**Usage Examples:**
268
269
```javascript
270
// Get metadata for a specific package
271
const metadata = shrinkwrap.get('node_modules/express');
272
if (metadata) {
273
console.log(`Express metadata:`, metadata);
274
}
275
276
// Add node to lockfile
277
shrinkwrap.add(expressNode);
278
279
// Add edge metadata
280
shrinkwrap.addEdge(dependencyEdge);
281
282
// Remove package from lockfile
283
shrinkwrap.delete('node_modules/old-package');
284
```
285
286
### Serialization
287
288
Methods for converting shrinkwrap data to string representations.
289
290
```javascript { .api }
291
/**
292
* Convert to string representation
293
* @param options - String conversion options
294
* @returns JSON string representation
295
*/
296
toString(options?: object): string;
297
298
/**
299
* Convert to JSON representation
300
* @returns JSON object representation
301
*/
302
toJSON(): object;
303
```
304
305
**Usage Examples:**
306
307
```javascript
308
// Get JSON string
309
const jsonString = shrinkwrap.toString();
310
311
// Get formatted JSON string
312
const formattedString = shrinkwrap.toString({ format: true });
313
314
// Get JSON object
315
const jsonObject = shrinkwrap.toJSON();
316
```
317
318
### Yarn Integration
319
320
Methods for working with yarn.lock files alongside npm lockfiles.
321
322
```javascript { .api }
323
/**
324
* Check a spec against yarn.lock
325
* @param spec - Package spec to check
326
* @param options - Check options
327
* @returns Yarn lock entry or null
328
*/
329
checkYarnLock(spec: string, options?: object): any;
330
```
331
332
**Usage Example:**
333
334
```javascript
335
// Check yarn.lock for package
336
const yarnEntry = shrinkwrap.checkYarnLock('express@^4.18.0');
337
if (yarnEntry) {
338
console.log('Found in yarn.lock:', yarnEntry);
339
}
340
```
341
342
### Formatting
343
344
Methods for inferring and setting formatting options.
345
346
```javascript { .api }
347
/**
348
* Infer formatting options from package.json
349
* @param packageJSONData - Package.json content
350
*/
351
inferFormattingOptions(packageJSONData: object): void;
352
```
353
354
**Usage Example:**
355
356
```javascript
357
// Infer formatting from package.json
358
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
359
shrinkwrap.inferFormattingOptions(packageJson);
360
```
361
362
## Lockfile Versions
363
364
### Version 1 (Legacy)
365
366
Original npm lockfile format with basic dependency tracking.
367
368
```javascript
369
const v1Shrinkwrap = new Shrinkwrap({
370
lockfileVersion: 1,
371
path: '/project'
372
});
373
```
374
375
### Version 2 (npm 6+)
376
377
Enhanced format with improved metadata and deduplication tracking.
378
379
```javascript
380
const v2Shrinkwrap = new Shrinkwrap({
381
lockfileVersion: 2,
382
path: '/project'
383
});
384
```
385
386
### Version 3 (npm 7+)
387
388
Latest format with workspace support and enhanced peer dependency tracking.
389
390
```javascript
391
const v3Shrinkwrap = new Shrinkwrap({
392
lockfileVersion: 3,
393
path: '/project'
394
});
395
```
396
397
## File Types
398
399
### package-lock.json
400
401
Standard npm lockfile, committed to version control.
402
403
```javascript
404
// Standard lockfile (default)
405
const packageLock = await Shrinkwrap.load({
406
path: '/project'
407
// Uses package-lock.json by default
408
});
409
```
410
411
### npm-shrinkwrap.json
412
413
Published lockfile that gets included in npm packages.
414
415
```javascript
416
// Shrinkwrap file (published)
417
const shrinkwrapFile = await Shrinkwrap.load({
418
path: '/project',
419
shrinkwrapOnly: true
420
});
421
```
422
423
### Hidden Lockfiles
424
425
Special lockfiles for internal use cases.
426
427
```javascript
428
// Hidden lockfile
429
const hiddenLock = new Shrinkwrap({
430
path: '/project',
431
hiddenLockfile: true
432
});
433
```
434
435
## Common Workflows
436
437
### Loading and Updating
438
439
```javascript
440
// Load existing lockfile
441
const shrinkwrap = await Shrinkwrap.load({ path: '/project' });
442
443
// Add new dependency metadata
444
shrinkwrap.add(newPackageNode);
445
446
// Save updated lockfile
447
await shrinkwrap.save();
448
```
449
450
### Version Migration
451
452
```javascript
453
// Load v2 lockfile
454
const oldShrinkwrap = await Shrinkwrap.load({ path: '/project' });
455
console.log(`Current version: ${oldShrinkwrap.lockfileVersion}`);
456
457
// Upgrade to v3
458
oldShrinkwrap.lockfileVersion = 3;
459
await oldShrinkwrap.save();
460
```
461
462
### Tree Synchronization
463
464
```javascript
465
// Sync shrinkwrap with tree
466
shrinkwrap.tree = rootNode;
467
468
// Add all nodes from tree
469
for (const node of rootNode.inventory.values()) {
470
shrinkwrap.add(node);
471
}
472
473
// Save synchronized lockfile
474
await shrinkwrap.save();
475
```