diff --git a/packages/core/integration-tests/test/integration/scope-hoisting/es6/unused-require/index.js b/packages/core/integration-tests/test/integration/scope-hoisting/es6/unused-require/index.js new file mode 100644 index 00000000000..5ed2ae0a6db --- /dev/null +++ b/packages/core/integration-tests/test/integration/scope-hoisting/es6/unused-require/index.js @@ -0,0 +1,3 @@ +import {foo} from './library'; + +output = foo; diff --git a/packages/core/integration-tests/test/integration/scope-hoisting/es6/unused-require/library/foo/index.js b/packages/core/integration-tests/test/integration/scope-hoisting/es6/unused-require/library/foo/index.js new file mode 100644 index 00000000000..6f1f6971ff2 --- /dev/null +++ b/packages/core/integration-tests/test/integration/scope-hoisting/es6/unused-require/library/foo/index.js @@ -0,0 +1,2 @@ +export const unusedFoo = 'unusedFoo'; +export { foo } from './other'; diff --git a/packages/core/integration-tests/test/integration/scope-hoisting/es6/unused-require/library/foo/other.js b/packages/core/integration-tests/test/integration/scope-hoisting/es6/unused-require/library/foo/other.js new file mode 100644 index 00000000000..3329a7d972f --- /dev/null +++ b/packages/core/integration-tests/test/integration/scope-hoisting/es6/unused-require/library/foo/other.js @@ -0,0 +1 @@ +export const foo = 'foo'; diff --git a/packages/core/integration-tests/test/integration/scope-hoisting/es6/unused-require/library/foo/package.json b/packages/core/integration-tests/test/integration/scope-hoisting/es6/unused-require/library/foo/package.json new file mode 100644 index 00000000000..a43829151e1 --- /dev/null +++ b/packages/core/integration-tests/test/integration/scope-hoisting/es6/unused-require/library/foo/package.json @@ -0,0 +1,3 @@ +{ + "sideEffects": false +} diff --git a/packages/core/integration-tests/test/integration/scope-hoisting/es6/unused-require/library/index.js b/packages/core/integration-tests/test/integration/scope-hoisting/es6/unused-require/library/index.js new file mode 100644 index 00000000000..cc44b9b5e6e --- /dev/null +++ b/packages/core/integration-tests/test/integration/scope-hoisting/es6/unused-require/library/index.js @@ -0,0 +1,3 @@ +export { foo, unusedFoo } from './foo'; + +eval('') diff --git a/packages/core/integration-tests/test/scope-hoisting.js b/packages/core/integration-tests/test/scope-hoisting.js index 39592f262c4..75af27f0f6d 100644 --- a/packages/core/integration-tests/test/scope-hoisting.js +++ b/packages/core/integration-tests/test/scope-hoisting.js @@ -5336,4 +5336,16 @@ describe('scope hoisting', function () { let output = await run(b); assert.strictEqual(output, 'bar foo bar'); }); + + it("not insert unused requires that aren't registered anywhere", async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/unused-require/index.js', + ), + ); + + let output = await run(b); + assert.strictEqual(output, 'foo'); + }); }); diff --git a/packages/packagers/js/src/ScopeHoistingPackager.js b/packages/packagers/js/src/ScopeHoistingPackager.js index c87451a3c19..ce69c263ff2 100644 --- a/packages/packagers/js/src/ScopeHoistingPackager.js +++ b/packages/packagers/js/src/ScopeHoistingPackager.js @@ -760,9 +760,18 @@ ${code} let staticExports = resolvedAsset.meta.staticExports !== false; let publicId = this.bundleGraph.getAssetPublicId(resolvedAsset); - // If the rsolved asset is wrapped, but imported at the top-level by this asset, + // If the resolved asset is wrapped, but imported at the top-level by this asset, // then we hoist parcelRequire calls to the top of this asset so side effects run immediately. - if (isWrapped && dep && !dep?.meta.shouldWrap && symbol !== false) { + if ( + isWrapped && + dep && + !dep?.meta.shouldWrap && + symbol !== false && + // Only do this if the asset is part of a different bundle (so it was definitely + // parcelRequire.register'ed there), or if it is indeed registered in this bundle. + (!this.bundle.hasAsset(resolvedAsset) || + !this.shouldSkipAsset(resolvedAsset)) + ) { let hoisted = this.hoistedRequires.get(dep.id); if (!hoisted) { hoisted = new Map();