Skip to content

Commit

Permalink
fix(link): do not prune packages
Browse files Browse the repository at this point in the history
`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: #2554
  • Loading branch information
ruyadorno committed Jun 10, 2021
1 parent 3f202cd commit da98092
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 0 deletions.
2 changes: 2 additions & 0 deletions lib/link.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,14 @@ class Link extends ArboristWorkspaceCmd {
// reify all the pending names as symlinks there
const localArb = new Arborist({
...this.npm.flatOptions,
prune: false,
log: this.npm.log,
path: this.npm.prefix,
save,
})
await localArb.reify({
...this.npm.flatOptions,
prune: false,
path: this.npm.prefix,
log: this.npm.log,
add: names.map(l => `file:${resolve(globalTop, 'node_modules', l)}`),
Expand Down
50 changes: 50 additions & 0 deletions test/lib/link.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const { resolve } = require('path')
const fs = require('fs')

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

t.test('should not prune dependencies when linking packages', async t => {
const testdir = t.testdir({
'global-prefix': {
lib: {
node_modules: {
linked: t.fixture('symlink', '../../../linked'),
},
},
},
linked: {
'package.json': JSON.stringify({
name: 'linked',
version: '1.0.0',
}),
},
'my-project': {
node_modules: {
foo: {
'package.json': JSON.stringify({ name: 'foo', version: '1.0.0' }),
},
},
'package.json': JSON.stringify({
name: 'my-project',
version: '1.0.0',
}),
},
})
npm.globalDir = resolve(testdir, 'global-prefix', 'lib', 'node_modules')
npm.prefix = resolve(testdir, 'my-project')
reifyOutput = () => {}

const _cwd = process.cwd()
process.chdir(npm.prefix)

await new Promise((res, rej) => {
link.exec(['linked'], (err) => {
if (err)
rej(err)
res()
})
})

t.ok(
fs.statSync(resolve(testdir, 'my-project/node_modules/foo')),
'should not prune any extraneous dep when running npm link'
)
process.chdir(_cwd)
})

t.test('completion', async t => {
const testdir = t.testdir({
'global-prefix': {
Expand Down

0 comments on commit da98092

Please sign in to comment.