diff --git a/lib/utils/validate-lockfile.js b/lib/utils/validate-lockfile.js index 9039a797c03dd..5947ab5c4323c 100644 --- a/lib/utils/validate-lockfile.js +++ b/lib/utils/validate-lockfile.js @@ -14,7 +14,11 @@ function validateLockfile (virtualTree, idealTree) { const lock = virtualTree.get(key) if (!lock) { - errors.push(`Missing: ${entry.name}@${entry.version} from lock file`) + // Bundled dependencies are extracted from their parent's tarball and + // may not have independent lockfile entries. + if (!entry.inBundle) { + errors.push(`Missing: ${entry.name}@${entry.version} from lock file`) + } continue } diff --git a/test/lib/utils/validate-lockfile.js b/test/lib/utils/validate-lockfile.js index cee1891f49183..c45d5a8fa9b21 100644 --- a/test/lib/utils/validate-lockfile.js +++ b/test/lib/utils/validate-lockfile.js @@ -131,6 +131,27 @@ t.test('extra inventory items on idealTree', async t => { ) }) +t.test('missing bundled inventory items do not invalidate lockfile', async t => { + const errors = validateLockfile( + new Map([ + ['node_modules/bundle', { name: 'bundle', version: '1.0.0' }], + ]), + new Map([ + ['node_modules/bundle', { name: 'bundle', version: '1.0.0' }], + ['node_modules/bundle/node_modules/embedded', { + name: 'embedded', + version: '1.0.0', + inBundle: true, + }], + ['node_modules/missing', { name: 'missing', version: '2.0.0' }], + ]) + ) + + t.strictSame(errors, [ + 'Missing: missing@2.0.0 from lock file', + ], 'bundled nodes are supplied by their parent tarball, while ordinary nodes remain required') +}) + t.test('extra inventory items on virtualTree', async t => { t.matchSnapshot( validateLockfile(