mirror of
https://github.com/pnpm/pnpm.git
synced 2026-07-26 07:27:20 -04:00
fix: re-add manually removed packages to node_modules when node-linker is set to hoisted (#5921)
This commit is contained in:
6
.changeset/rare-spoons-play.md
Normal file
6
.changeset/rare-spoons-play.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@pnpm/headless": patch
|
||||
"pnpm": patch
|
||||
---
|
||||
|
||||
If an external tool or a user have removed a package from node_modules, pnpm should add it back on install. This was only an issue with `node-linker=hoisted`.
|
||||
@@ -3,6 +3,7 @@ import path from 'path'
|
||||
import { addDependenciesToPackage, install, mutateModules, mutateModulesInSingleProject } from '@pnpm/core'
|
||||
import { prepareEmpty } from '@pnpm/prepare'
|
||||
import { addDistTag } from '@pnpm/registry-mock'
|
||||
import rimraf from '@zkochan/rimraf'
|
||||
import { sync as loadJsonFile } from 'load-json-file'
|
||||
import { sync as readYamlFile } from 'read-yaml-file'
|
||||
import symlinkDir from 'symlink-dir'
|
||||
@@ -11,13 +12,14 @@ import { testDefaults } from '../utils'
|
||||
test('installing with hoisted node-linker', async () => {
|
||||
prepareEmpty()
|
||||
|
||||
await install({
|
||||
const manifest = {
|
||||
dependencies: {
|
||||
send: '0.17.2',
|
||||
'has-flag': '1.0.0',
|
||||
ms: '1.0.0',
|
||||
},
|
||||
}, await testDefaults({
|
||||
}
|
||||
await install(manifest, await testDefaults({
|
||||
nodeLinker: 'hoisted',
|
||||
}))
|
||||
|
||||
@@ -27,6 +29,13 @@ test('installing with hoisted node-linker', async () => {
|
||||
expect(fs.existsSync('node_modules/send/node_modules/ms')).toBeTruthy()
|
||||
|
||||
expect(readYamlFile<{ nodeLinker: string }>('node_modules/.modules.yaml').nodeLinker).toBe('hoisted')
|
||||
|
||||
// If a package from node_modules is removed, it should be re-added.
|
||||
await rimraf('node_modules/send')
|
||||
await install(manifest, await testDefaults({
|
||||
nodeLinker: 'hoisted',
|
||||
}))
|
||||
expect(fs.realpathSync('node_modules/send')).toEqual(path.resolve('node_modules/send'))
|
||||
})
|
||||
|
||||
test('installing with hoisted node-linker and no lockfile', async () => {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import pathExists from 'path-exists'
|
||||
import path from 'path'
|
||||
import {
|
||||
Lockfile,
|
||||
@@ -181,7 +182,12 @@ async function fetchDeps (
|
||||
const depLocation = path.relative(opts.lockfileDir, dir)
|
||||
const resolution = pkgSnapshotToResolution(depPath, pkgSnapshot, opts.registries)
|
||||
let fetchResponse!: ReturnType<FetchPackageToStoreFunction>
|
||||
const skipFetch = opts.currentHoistedLocations?.[depPath]?.includes(depLocation)
|
||||
// We check for the existence of the package inside node_modules.
|
||||
// It will only be missing if the user manually removed it.
|
||||
// That shouldn't normally happen but Bit CLI does remove node_modules in component directories:
|
||||
// https://github.com/teambit/bit/blob/5e1eed7cd122813ad5ea124df956ee89d661d770/scopes/dependencies/dependency-resolver/dependency-installer.ts#L169
|
||||
const skipFetch = opts.currentHoistedLocations?.[depPath]?.includes(depLocation) &&
|
||||
await pathExists(path.join(opts.lockfileDir, depLocation))
|
||||
const pkgResolution = {
|
||||
id: packageId,
|
||||
resolution,
|
||||
|
||||
Reference in New Issue
Block a user