feat(overrides): remove dependencies (#8576)

close #8572
This commit is contained in:
Khải
2024-09-28 19:27:13 +07:00
committed by GitHub
parent f6e9677e04
commit b7fb704522
4 changed files with 143 additions and 5 deletions

View File

@@ -0,0 +1,17 @@
---
"@pnpm/hooks.read-package-hook": minor
"pnpm": minor
---
Added the ability for `overrides` to remove dependencies by specifying `"-"` as the field value [#8572](https://github.com/pnpm/pnpm/issues/8572). For example, to remove `lodash` from the dependencies, use this configuration in `package.json`:
```json
{
"pnpm": {
"overrides": {
"lodash": "-"
}
}
}
```

View File

@@ -97,6 +97,11 @@ function overrideDeps (
)
if (!versionOverride) continue
if (versionOverride.newPref === '-') {
delete deps[versionOverride.targetPkg.name]
continue
}
if (versionOverride.localTarget) {
deps[versionOverride.targetPkg.name] = `${versionOverride.localTarget.protocol}${resolveLocalOverride(versionOverride.localTarget, dir)}`
continue

View File

@@ -1,5 +1,5 @@
import path from 'path'
import { createVersionsOverrider } from '../lib/createVersionsOverrider'
import { createVersionsOverrider } from '../src/createVersionsOverrider'
test('createVersionsOverrider() matches sub-ranges', () => {
const overrider = createVersionsOverrider([
@@ -615,3 +615,77 @@ test('createVersionsOverrider() overrides peerDependencies of another dependency
},
})
})
test('createVersionOverrider() removes dependencies', () => {
const overrider = createVersionsOverrider([
{
targetPkg: {
name: 'foo',
},
newPref: '-',
},
{
parentPkg: {
name: 'bar',
},
targetPkg: {
name: 'baz',
},
newPref: '-',
},
{
targetPkg: {
name: 'qux',
pref: '2',
},
newPref: '-',
},
], process.cwd())
expect(
overrider({
dependencies: {
foo: '0.1.2',
bar: '1.2.3',
baz: '1.0.0',
qux: '2.1.0',
},
})
).toStrictEqual({
dependencies: {
bar: '1.2.3',
baz: '1.0.0',
},
})
expect(
overrider({
name: 'bar',
dependencies: {
foo: '0.1.2',
bar: '1.2.3',
baz: '1.0.0',
qux: '2.1.0',
},
})
).toStrictEqual({
name: expect.anything(),
dependencies: {
bar: '1.2.3',
},
})
expect(
overrider({
dependencies: {
foo: '0.1.2',
bar: '1.2.3',
baz: '1.0.0',
qux: '3.2.1',
},
})
).toStrictEqual({
dependencies: {
bar: '1.2.3',
baz: '1.0.0',
qux: '3.2.1',
},
})
})

View File

@@ -2,15 +2,13 @@ import path from 'path'
import fs from 'fs'
import { sync as readYamlFile } from 'read-yaml-file'
import { PnpmError } from '@pnpm/error'
import { prepareEmpty, preparePackages } from '@pnpm/prepare'
import { prepare, prepareEmpty, preparePackages } from '@pnpm/prepare'
import { addDistTag } from '@pnpm/registry-mock'
import { WANTED_LOCKFILE } from '@pnpm/constants'
import { type MutatedProject, type ProjectOptions, addDependenciesToPackage, mutateModulesInSingleProject, mutateModules } from '@pnpm/core'
import { type LockfileFileV9 } from '@pnpm/lockfile.types'
import { type ProjectRootDir, type ProjectManifest } from '@pnpm/types'
import {
testDefaults,
} from '../utils'
import { testDefaults } from '../utils'
test('versions are replaced with versions specified through overrides option', async () => {
const project = prepareEmpty()
@@ -252,3 +250,47 @@ test('overrides with local file and link specs', async () => {
expect(fs.realpathSync(path.join(indirectPrefix, '@pnpm.e2e/pkg-c'))).toBe(path.resolve('overrides/pkg'))
expect(fs.realpathSync(path.join(indirectPrefix, '@pnpm.e2e/pkg-d'))).toBe(path.resolve('overrides/pkg'))
})
test('overrides remove dependencies', async () => {
const manifest: ProjectManifest = {
dependencies: {
'@pnpm.e2e/pkg-with-good-optional': '1.0.0',
},
pnpm: {
overrides: {
'@pnpm.e2e/pkg-with-good-optional>is-positive': '-',
},
},
}
const project = prepare(manifest)
await mutateModulesInSingleProject({
manifest,
mutation: 'install',
rootDir: process.cwd() as ProjectRootDir,
}, testDefaults({
overrides: manifest.pnpm?.overrides,
}))
// assert that @pnpm.e2e/pkg-with-good-optional@1.0.0 depends on is-positive@1.0.0
expect(project.requireModule('@pnpm.e2e/pkg-with-good-optional/package.json')).toMatchObject({
version: '1.0.0',
optionalDependencies: {
'is-positive': '1.0.0',
},
})
// yet because of the overrides, it installs @pnpm.e2e/pkg-with-good-optional@1.0.0 without is-positive@1.0.0
const lockfile = project.readLockfile()
expect(lockfile.snapshots).toHaveProperty(['@pnpm.e2e/pkg-with-good-optional@1.0.0'])
expect(lockfile.snapshots['@pnpm.e2e/pkg-with-good-optional@1.0.0']).not.toHaveProperty(['optionalDependencies', 'is-positive'])
expect(lockfile.snapshots).not.toHaveProperty(['is-positive@1.0.0'])
expect(lockfile.packages).toHaveProperty(['@pnpm.e2e/pkg-with-good-optional@1.0.0'])
expect(lockfile.packages).not.toHaveProperty(['is-positive@1.0.0'])
expect(
fs.existsSync('node_modules/.pnpm/@pnpm.e2e+pkg-with-good-optional@1.0.0/node_modules/is-positive')
).toBe(false)
const currentLockfile = project.readCurrentLockfile()
expect(lockfile.overrides).toStrictEqual(currentLockfile.overrides)
})