fix: don't remove hoisted dependencies from .pnpm on repeat install (#5971)

This commit is contained in:
Zoltan Kochan
2023-01-22 20:03:30 +02:00
committed by GitHub
parent 5a00b705a3
commit 1072ec1286
4 changed files with 26 additions and 4 deletions

View File

@@ -0,0 +1,7 @@
---
"@pnpm/modules-cleaner": patch
"@pnpm/core": patch
"pnpm": patch
---
Packages hoisted to the virtual store are not removed on repeat install, when the non-headless algorithm runs the installation.

View File

@@ -245,7 +245,9 @@ export async function linkPackages (
}
let newHoistedDependencies!: HoistedDependencies
if ((opts.hoistPattern != null || opts.publicHoistPattern != null) && (newDepPaths.length > 0 || removedDepPaths.size > 0)) {
if (opts.hoistPattern == null && opts.publicHoistPattern == null) {
newHoistedDependencies = {}
} else if (newDepPaths.length > 0 || removedDepPaths.size > 0) {
// It is important to keep the skipped packages in the lockfile which will be saved as the "current lockfile".
// pnpm is comparing the current lockfile to the wanted one and they should match.
// But for hoisting, we need a version of the lockfile w/o the skipped packages, so we're making a copy.
@@ -264,7 +266,7 @@ export async function linkPackages (
virtualStoreDir: opts.virtualStoreDir,
})
} else {
newHoistedDependencies = {}
newHoistedDependencies = opts.hoistedDependencies
}
return {

View File

@@ -20,7 +20,7 @@ import { testDefaults } from '../utils'
test('should hoist dependencies', async () => {
const project = prepareEmpty()
await addDependenciesToPackage({}, ['express', '@foo/has-dep-from-same-scope'], await testDefaults({ fastUnpack: false, hoistPattern: '*' }))
const manifest = await addDependenciesToPackage({}, ['express', '@foo/has-dep-from-same-scope'], await testDefaults({ fastUnpack: false, hoistPattern: '*' }))
await project.has('express')
await project.has('.pnpm/node_modules/debug')
@@ -31,6 +31,19 @@ test('should hoist dependencies', async () => {
// should also hoist bins
await project.isExecutable('.pnpm/node_modules/.bin/mime')
const modules = await project.readModulesManifest()
expect(Object.keys(modules!.hoistedDependencies).length > 0).toBeTruthy()
// On repeat install the hoisted packages are preserved (non-headless install)
await install(manifest, await testDefaults({ fastUnpack: false, hoistPattern: '*', preferFrozenLockfile: false, modulesCacheMaxAge: 0 }))
await project.has('.pnpm/node_modules/debug')
expect((await project.readModulesManifest())!.hoistedDependencies).toStrictEqual(modules!.hoistedDependencies)
// On repeat install the hoisted packages are preserved (headless install)
await install(manifest, await testDefaults({ fastUnpack: false, hoistPattern: '*', frozenLockfile: true, modulesCacheMaxAge: 0 }))
await project.has('.pnpm/node_modules/debug')
expect((await project.readModulesManifest())!.hoistedDependencies).toStrictEqual(modules!.hoistedDependencies)
})
test('should hoist dependencies to the root of node_modules when publicHoistPattern is used', async () => {

View File

@@ -156,7 +156,7 @@ export async function prune (
.map((orphanDepPath) => depPathToFilename(orphanDepPath))
.map(async (orphanDepPath) => _tryRemovePkg(orphanDepPath))
)
const neededPkgs: Set<string> = new Set()
const neededPkgs: Set<string> = new Set(['node_modules'])
for (const depPath of Object.keys(opts.wantedLockfile.packages ?? {})) {
if (opts.skipped.has(depPath)) continue
neededPkgs.add(depPathToFilename(depPath))