Skip to content

Commit da98092

Browse files
committed
fix(link): do not prune packages
`npm link <pkg>` is meant to be used as a way to link a local package to an install tree and it's very surprising to users that it may prune extraneous deps from the project. This change switches the default behavior to avoid pruning deps when reifying the dependencies in npm link. Fixes: npm#2554
1 parent 3f202cd commit da98092

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

lib/link.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,14 @@ class Link extends ArboristWorkspaceCmd {
134134
// reify all the pending names as symlinks there
135135
const localArb = new Arborist({
136136
...this.npm.flatOptions,
137+
prune: false,
137138
log: this.npm.log,
138139
path: this.npm.prefix,
139140
save,
140141
})
141142
await localArb.reify({
142143
...this.npm.flatOptions,
144+
prune: false,
143145
path: this.npm.prefix,
144146
log: this.npm.log,
145147
add: names.map(l => `file:${resolve(globalTop, 'node_modules', l)}`),

test/lib/link.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const { resolve } = require('path')
2+
const fs = require('fs')
23

34
const Arborist = require('@npmcli/arborist')
45
const t = require('tap')
@@ -485,6 +486,55 @@ t.test('link pkg already in global space when prefix is a symlink', (t) => {
485486
})
486487
})
487488

489+
t.test('should not prune dependencies when linking packages', async t => {
490+
const testdir = t.testdir({
491+
'global-prefix': {
492+
lib: {
493+
node_modules: {
494+
linked: t.fixture('symlink', '../../../linked'),
495+
},
496+
},
497+
},
498+
linked: {
499+
'package.json': JSON.stringify({
500+
name: 'linked',
501+
version: '1.0.0',
502+
}),
503+
},
504+
'my-project': {
505+
node_modules: {
506+
foo: {
507+
'package.json': JSON.stringify({ name: 'foo', version: '1.0.0' }),
508+
},
509+
},
510+
'package.json': JSON.stringify({
511+
name: 'my-project',
512+
version: '1.0.0',
513+
}),
514+
},
515+
})
516+
npm.globalDir = resolve(testdir, 'global-prefix', 'lib', 'node_modules')
517+
npm.prefix = resolve(testdir, 'my-project')
518+
reifyOutput = () => {}
519+
520+
const _cwd = process.cwd()
521+
process.chdir(npm.prefix)
522+
523+
await new Promise((res, rej) => {
524+
link.exec(['linked'], (err) => {
525+
if (err)
526+
rej(err)
527+
res()
528+
})
529+
})
530+
531+
t.ok(
532+
fs.statSync(resolve(testdir, 'my-project/node_modules/foo')),
533+
'should not prune any extraneous dep when running npm link'
534+
)
535+
process.chdir(_cwd)
536+
})
537+
488538
t.test('completion', async t => {
489539
const testdir = t.testdir({
490540
'global-prefix': {

0 commit comments

Comments
 (0)