diff --git a/packages/core/core/src/BundleGraph.js b/packages/core/core/src/BundleGraph.js index 537ecc0f78a..3f0de396c84 100644 --- a/packages/core/core/src/BundleGraph.js +++ b/packages/core/core/src/BundleGraph.js @@ -860,10 +860,12 @@ export default class BundleGraph { traverseAssets( bundle: Bundle, visit: GraphVisitor, + startAsset?: Asset, ): ?TContext { return this.traverseBundle( bundle, mapVisitor(node => (node.type === 'asset' ? node.value : null), visit), + startAsset, ); } @@ -1057,8 +1059,9 @@ export default class BundleGraph { traverseBundle( bundle: Bundle, visit: GraphVisitor, + startAsset?: Asset, ): ?TContext { - let entries = true; + let entries = !startAsset; let bundleNodeId = this._graph.getNodeIdByContentKey(bundle.id); // A modified DFS traversal which traverses entry assets in the same order @@ -1085,7 +1088,9 @@ export default class BundleGraph { actions.skipChildren(); }, visit), - startNodeId: bundleNodeId, + startNodeId: startAsset + ? this._graph.getNodeIdByContentKey(startAsset.id) + : bundleNodeId, getChildren: nodeId => { let children = this._graph .getNodeIdsConnectedFrom(nodeId) diff --git a/packages/core/core/src/public/Bundle.js b/packages/core/core/src/public/Bundle.js index 3581678d33d..fb95d1a5359 100644 --- a/packages/core/core/src/public/Bundle.js +++ b/packages/core/core/src/public/Bundle.js @@ -186,10 +186,14 @@ export class Bundle implements IBundle { ); } - traverseAssets(visit: GraphVisitor): ?TContext { + traverseAssets( + visit: GraphVisitor, + startAsset?: IAsset, + ): ?TContext { return this.#bundleGraph.traverseAssets( this.#bundle, mapVisitor(asset => assetFromValue(asset, this.#options), visit), + startAsset ? assetToAssetValue(startAsset) : undefined, ); } } diff --git a/packages/core/types/index.js b/packages/core/types/index.js index c79df875b66..5cc58c64d1c 100644 --- a/packages/core/types/index.js +++ b/packages/core/types/index.js @@ -1243,7 +1243,10 @@ export interface Bundle { /** Returns whether the bundle includes the given dependency. */ hasDependency(Dependency): boolean; /** Traverses the assets in the bundle. */ - traverseAssets(visit: GraphVisitor): ?TContext; + traverseAssets( + visit: GraphVisitor, + startAsset?: Asset, + ): ?TContext; /** Traverses assets and dependencies in the bundle. */ traverse( visit: GraphVisitor, diff --git a/packages/packagers/js/src/ScopeHoistingPackager.js b/packages/packagers/js/src/ScopeHoistingPackager.js index 87ed3952bd1..36cc5422e5a 100644 --- a/packages/packagers/js/src/ScopeHoistingPackager.js +++ b/packages/packagers/js/src/ScopeHoistingPackager.js @@ -241,7 +241,7 @@ export class ScopeHoistingPackager { async loadAssets(): Promise> { let queue = new PromiseQueue({maxConcurrent: 32}); let wrapped = []; - this.bundle.traverseAssets((asset, shouldWrap) => { + this.bundle.traverseAssets(asset => { queue.add(async () => { let [code, map] = await Promise.all([ asset.getCode(), @@ -251,7 +251,6 @@ export class ScopeHoistingPackager { }); if ( - shouldWrap || asset.meta.shouldWrap || this.isAsyncBundle || this.bundle.env.sourceType === 'script' || @@ -262,10 +261,21 @@ export class ScopeHoistingPackager { ) { this.wrappedAssets.add(asset.id); wrapped.push(asset); - return true; } }); + for (let wrappedAsset of [...wrapped]) { + this.bundle.traverseAssets((asset, _, actions) => { + if (asset !== wrappedAsset && this.wrappedAssets.has(asset.id)) { + actions.skipChildren(); + return; + } + + this.wrappedAssets.add(asset.id); + wrapped.push(asset); + }, wrappedAsset); + } + this.assetOutputs = new Map(await queue.run()); return wrapped; }