Skip to content

Commit 8cf2689

Browse files
committed
fix!: refuse to pack with bundled dependencies AND overrides
BREAKING CHANGE: npm pack and npm publish now error when a package defines both bundledDependencies (or bundleDependencies) and overrides. Remove one of the fields from package.json to publish.
1 parent 01d9acd commit 8cf2689

2 files changed

Lines changed: 92 additions & 0 deletions

File tree

workspaces/libnpmpack/lib/index.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,20 @@ async function pack (spec = 'file:.', opts = {}) {
1414

1515
const manifest = await pacote.manifest(spec, { ...opts, Arborist, _isRoot: true })
1616

17+
if (spec.type === 'directory') {
18+
const bundled = manifest.bundledDependencies || manifest.bundleDependencies
19+
const hasBundled = Array.isArray(bundled) ? bundled.length > 0 : Boolean(bundled)
20+
const hasOverrides = manifest.overrides
21+
&& typeof manifest.overrides === 'object'
22+
&& Object.keys(manifest.overrides).length > 0
23+
if (hasBundled && hasOverrides) {
24+
throw Object.assign(
25+
new Error('Cannot pack or publish a package that has both bundled dependencies and overrides. Remove either the "bundledDependencies"/"bundleDependencies" or "overrides" field from package.json before publishing.'),
26+
{ code: 'EBUNDLEOVERRIDE' }
27+
)
28+
}
29+
}
30+
1731
const stdio = opts.foregroundScripts ? 'inherit' : 'pipe'
1832

1933
if (spec.type === 'directory' && !opts.ignoreScripts) {

workspaces/libnpmpack/test/index.js

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,3 +212,81 @@ t.test('doesn\'t run scripts when ignoreScripts === true', async t => {
212212
spawk.clean()
213213
})
214214
})
215+
216+
t.test('refuses to pack with both bundledDependencies and overrides', async t => {
217+
const testDir = t.testdir({
218+
'package.json': JSON.stringify({
219+
name: 'my-cool-pkg',
220+
version: '1.0.0',
221+
bundledDependencies: ['semver'],
222+
dependencies: { semver: '7.5.0' },
223+
overrides: { 'lru-cache': '6.0.0' },
224+
}, null, 2),
225+
})
226+
227+
const cwd = process.cwd()
228+
process.chdir(testDir)
229+
t.teardown(() => process.chdir(cwd))
230+
231+
await t.rejects(
232+
pack('file:.'),
233+
{ code: 'EBUNDLEOVERRIDE' },
234+
'throws with EBUNDLEOVERRIDE code'
235+
)
236+
})
237+
238+
t.test('refuses to pack with bundleDependencies (alt spelling) and overrides', async t => {
239+
const testDir = t.testdir({
240+
'package.json': JSON.stringify({
241+
name: 'my-cool-pkg',
242+
version: '1.0.0',
243+
bundleDependencies: ['semver'],
244+
dependencies: { semver: '7.5.0' },
245+
overrides: { 'lru-cache': '6.0.0' },
246+
}, null, 2),
247+
})
248+
249+
const cwd = process.cwd()
250+
process.chdir(testDir)
251+
t.teardown(() => process.chdir(cwd))
252+
253+
await t.rejects(
254+
pack('file:.'),
255+
{ code: 'EBUNDLEOVERRIDE' },
256+
'throws with EBUNDLEOVERRIDE code'
257+
)
258+
})
259+
260+
t.test('packs with only bundledDependencies (no overrides)', async t => {
261+
const testDir = t.testdir({
262+
'package.json': JSON.stringify({
263+
name: 'my-cool-pkg',
264+
version: '1.0.0',
265+
bundledDependencies: [],
266+
}, null, 2),
267+
})
268+
269+
const cwd = process.cwd()
270+
process.chdir(testDir)
271+
t.teardown(() => process.chdir(cwd))
272+
273+
const tarball = await pack('file:.')
274+
t.ok(tarball)
275+
})
276+
277+
t.test('packs with only overrides (no bundled)', async t => {
278+
const testDir = t.testdir({
279+
'package.json': JSON.stringify({
280+
name: 'my-cool-pkg',
281+
version: '1.0.0',
282+
overrides: { 'lru-cache': '6.0.0' },
283+
}, null, 2),
284+
})
285+
286+
const cwd = process.cwd()
287+
process.chdir(testDir)
288+
t.teardown(() => process.chdir(cwd))
289+
290+
const tarball = await pack('file:.')
291+
t.ok(tarball)
292+
})

0 commit comments

Comments
 (0)