From ef84fc62860070762a96c600ca5b1622c6e3f1b9 Mon Sep 17 00:00:00 2001 From: Agnieszka Gawrys Date: Tue, 12 Jul 2022 10:42:22 -0400 Subject: [PATCH 01/10] consider reused bundles as shared bundles, turn source bundles into set, add tests for removal based on limit and size --- .../experimental/src/ExperimentalBundler.js | 169 +++++++------- .../core/integration-tests/test/bundler.js | 214 +++++++++++------- .../bar.js | 5 + .../buzz.js | 1 + .../c.js | 7 + .../foo.js | 3 + .../index.js | 5 + .../local.html | 6 + .../package.json | 6 + .../styles.css | 1 + .../yarn.lock | 0 .../a.js | 3 + .../b.js | 2 + .../bar.js | 7 + .../buzz.js | 1 + .../c.js | 7 + .../foo.js | 4 + .../index.js | 5 + .../local.html | 6 + .../package.json | 6 + .../styles.css | 1 + .../yarn.lock | 0 .../a.js | 9 + .../b.js | 7 + .../bar.js | 7 + .../buzz.js | 1 + .../c.js | 7 + .../foo.js | 4 + .../index.js | 5 + .../local.html | 6 + .../package.json | 6 + .../styles.css | 1 + .../yarn.lock | 0 33 files changed, 348 insertions(+), 164 deletions(-) create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/bar.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/buzz.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/c.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/foo.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/index.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/local.html create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/package.json create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/styles.css create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/yarn.lock create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/a.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/b.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/bar.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/buzz.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/c.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/foo.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/index.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/local.html create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/package.json create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/styles.css create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/yarn.lock create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/a.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/b.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/bar.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/buzz.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/c.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/foo.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/index.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/local.html create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/package.json create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/styles.css create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/yarn.lock diff --git a/packages/bundlers/experimental/src/ExperimentalBundler.js b/packages/bundlers/experimental/src/ExperimentalBundler.js index 920f8f3a5e1..9a5b06a0d39 100644 --- a/packages/bundlers/experimental/src/ExperimentalBundler.js +++ b/packages/bundlers/experimental/src/ExperimentalBundler.js @@ -68,7 +68,7 @@ export type Bundle = {| needsStableName: boolean, mainEntryAsset: ?Asset, size: number, - sourceBundles: Array, + sourceBundles: Set, target: Target, env: Environment, type: string, @@ -99,7 +99,6 @@ type IdealGraph = {| bundleGraph: Graph, bundleGroupBundleIds: Set, assetReference: DefaultMap>, - sharedToSourceBundleIds: Map>, |}; /** @@ -146,10 +145,8 @@ function decorateLegacyGraph( bundleGraph: idealBundleGraph, dependencyBundleGraph, bundleGroupBundleIds, - sharedToSourceBundleIds, } = idealGraph; let entryBundleToBundleGroup: Map = new Map(); - // Step Create Bundles: Create bundle groups, bundles, and shared bundles and add assets to them for (let [bundleNodeId, idealBundle] of idealBundleGraph.nodes) { if (idealBundle === 'root') continue; @@ -187,12 +184,12 @@ function decorateLegacyGraph( ); bundleGraph.addBundleToBundleGroup(bundle, bundleGroup); - } else if (idealBundle.sourceBundles.length > 0) { + } else if (idealBundle.sourceBundles.size > 0) { bundle = nullthrows( bundleGraph.createBundle({ uniqueKey: [...idealBundle.assets].map(asset => asset.id).join(',') + - idealBundle.sourceBundles.join(','), + [...idealBundle.sourceBundles].join(','), needsStableName: idealBundle.needsStableName, bundleBehavior: idealBundle.bundleBehavior, type: idealBundle.type, @@ -229,7 +226,6 @@ function decorateLegacyGraph( bundleGraph.addAssetToBundle(asset, bundle); } } - // Step Internalization: Internalize dependencies for bundles for (let [, idealBundle] of idealBundleGraph.nodes) { if (idealBundle === 'root') continue; @@ -283,20 +279,26 @@ function decorateLegacyGraph( } } - for (let [sharedBundleId, sourceBundleIds] of sharedToSourceBundleIds) { - let sharedBundle = nullthrows(idealBundleGraph.getNode(sharedBundleId)); - if (sharedBundle === 'root') continue; - let legacySharedBundle = nullthrows( - idealBundleToLegacyBundle.get(sharedBundle), + for (let {from, to} of idealBundleGraph.getAllEdges()) { + let sourceBundle = nullthrows(idealBundleGraph.getNode(from)); + if (sourceBundle === 'root') { + continue; + } + invariant(sourceBundle !== 'root'); + + let legacySourceBundle = nullthrows( + idealBundleToLegacyBundle.get(sourceBundle), ); - for (let sourceBundleId of sourceBundleIds) { - let sourceBundle = nullthrows(idealBundleGraph.getNode(sourceBundleId)); - if (sourceBundle === 'root') continue; - let legacySourceBundle = nullthrows( - idealBundleToLegacyBundle.get(sourceBundle), - ); - bundleGraph.createBundleReference(legacySourceBundle, legacySharedBundle); + + let targetBundle = nullthrows(idealBundleGraph.getNode(to)); + if (targetBundle === 'root') { + continue; } + invariant(targetBundle !== 'root'); + let legacyTargetBundle = nullthrows( + idealBundleToLegacyBundle.get(targetBundle), + ); + bundleGraph.createBundleReference(legacySourceBundle, legacyTargetBundle); } } @@ -334,8 +336,6 @@ function createIdealGraph( // Models bundleRoots and the assets that require it synchronously let reachableRoots: ContentGraph = new ContentGraph(); - let sharedToSourceBundleIds: Map> = new Map(); - let rootNodeId = nullthrows(bundleRootGraph.addNode('root')); let bundleGraphRootNodeId = nullthrows(bundleGraph.addNode('root')); bundleRootGraph.setRootNodeId(rootNodeId); @@ -902,16 +902,21 @@ function createIdealGraph( // if a bundle b is a subgraph of another bundle f, reuse it, drawing an edge between the two reachable = reachable.filter(b => { + let bundleBid = nullthrows(bundles.get(b.id)); if (b.env.isIsolated()) { return true; } let toKeep = true; if (bundles.has(asset.id)) { + let bundleRootBundleId = nullthrows(bundles.get(asset.id)); toKeep = false; bundleGraph.addEdge( nullthrows(bundles.get(b.id)), nullthrows(bundles.get(asset.id)), ); + let bundleOfAsset = bundleGraph.getNode(bundleRootBundleId); + invariant(bundleOfAsset !== 'root' && bundleOfAsset != null); + bundleOfAsset.sourceBundles.add(bundleBid); } for (let f of reachable) { if (b === f) continue; @@ -919,11 +924,12 @@ function createIdealGraph( b => !ancestorAssets.get(b)?.has(f), ); if (fReachable.indexOf(b) > -1) { + let bundleFid = nullthrows(bundles.get(f.id)); toKeep = false; - bundleGraph.addEdge( - nullthrows(bundles.get(b.id)), - nullthrows(bundles.get(f.id)), - ); + bundleGraph.addEdge(nullthrows(bundles.get(b.id)), bundleFid); + let bundleF = bundleGraph.getNode(bundleFid); + invariant(bundleF !== 'root' && bundleF != null); + bundleF.sourceBundles.add(bundleBid); } } return toKeep; @@ -954,7 +960,7 @@ function createIdealGraph( type: firstSourceBundle.type, env: firstSourceBundle.env, }); - bundle.sourceBundles = sourceBundles; + bundle.sourceBundles = new Set(sourceBundles); let sharedInternalizedAssets = new Set( firstSourceBundle.internalizedAssetIds, ); @@ -983,7 +989,6 @@ function createIdealGraph( bundleGraph.addEdge(sourceBundleId, bundleId); } } - sharedToSourceBundleIds.set(bundleId, sourceBundles); dependencyBundleGraph.addNodeByContentKeyIfNeeded(String(bundleId), { value: bundle, @@ -991,40 +996,36 @@ function createIdealGraph( }); } } - // Step Merge Share Bundles: Merge any shared bundles under the minimum bundle size back into // their source bundles, and remove the bundle. + // We should include "bundle reuse" as shared bundles that may be removed but the bundle itself would have to be retained for (let [bundleNodeId, bundle] of bundleGraph.nodes) { if (bundle === 'root') continue; - if (bundle.sourceBundles.length > 0 && bundle.size < config.minBundleSize) { - sharedToSourceBundleIds.delete(bundleNodeId); + if (bundle.sourceBundles.size > 0 && bundle.size < config.minBundleSize) { removeBundle(bundleGraph, bundleNodeId, assetReference); } } // Step Remove Shared Bundles: Remove shared bundles from bundle groups that hit the parallel request limit. - for (let [bundleId, bundleGroupId] of bundleRoots.values()) { - // Only handle bundle group entries. - if (bundleId !== bundleGroupId) { - continue; - } - + for (let bundleGroupId of bundleGraph.getNodeIdsConnectedFrom(rootNodeId)) { // Find shared bundles in this bundle group. - let bundleIdsInGroup = []; - for (let [ - sharedBundleId, - sourceBundleIds, - ] of sharedToSourceBundleIds.entries()) { - // If the bundle group's entry is a source bundle of this shared bundle, - // the shared bundle is part of the bundle group. - if (sourceBundleIds.includes(bundleId)) { - bundleIdsInGroup.push(sharedBundleId); - } - } + let bundleId = bundleGroupId; + // We should include "bundle reuse" as shared bundles that may be removed but the bundle itself would have to be retained + let bundleIdsInGroup = getBundlesForBundleGroup(bundleId); //get all bundlegrups this bundle is an ancestor of if (bundleIdsInGroup.length > config.maxParallelRequests) { + let sharedBundleIdsInBundleGroup = bundleIdsInGroup.filter(b => { + let bundle = nullthrows(bundleGraph.getNode(b)); + // shared bundles must have source bundles, we could have a bundle + // connected to another bundle that isnt a shared bundle, so check + return ( + bundle !== 'root' && bundle.sourceBundles.size > 0 && bundleId != b + ); + }); + + let numBundlesInGroup = bundleIdsInGroup.length; // Sort the bundles so the smallest ones are removed first. - let bundlesInGroup = bundleIdsInGroup + let sharedBundlesInGroup = sharedBundleIdsInBundleGroup .map(id => ({ id, bundle: nullthrows(bundleGraph.getNode(id)), @@ -1034,47 +1035,51 @@ function createIdealGraph( invariant(bundle !== 'root'); return {id, bundle}; }) - .sort((a, b) => a.bundle.size - b.bundle.size); + .sort((a, b) => b.bundle.size - a.bundle.size); // Remove bundles until the bundle group is within the parallel request limit. - for ( - let i = 0; - i < bundlesInGroup.length - config.maxParallelRequests; - i++ + while ( + sharedBundlesInGroup.length > 0 && + numBundlesInGroup > config.maxParallelRequests ) { - let bundleToRemove = bundlesInGroup[i].bundle; - let bundleIdToRemove = bundlesInGroup[i].id; + let bundleTuple = sharedBundlesInGroup.pop(); + let bundleToRemove = bundleTuple.bundle; + let bundleIdToRemove = bundleTuple.id; + //TODO add integration test where bundles in bunlde group > max parallel request limit & only remove a couple shared bundles + // but total # bundles still exceeds limit due to non shared bundles // Add all assets in the shared bundle into the source bundles that are within this bundle group. - let sourceBundles = bundleToRemove.sourceBundles - .filter(b => bundlesInGroup.map(b => b.bundle).includes(b)) - .map(id => nullthrows(bundleGraph.getNode(id))); + let sourceBundles = [...bundleToRemove.sourceBundles].filter(b => + bundleIdsInGroup.includes(b), + ); - for (let sourceBundle of sourceBundles) { + for (let sourceBundleId of sourceBundles) { + let sourceBundle = nullthrows(bundleGraph.getNode(sourceBundleId)); invariant(sourceBundle !== 'root'); + bundleToRemove.sourceBundles.delete(sourceBundleId); for (let asset of bundleToRemove.assets) { sourceBundle.assets.add(asset); sourceBundle.size += asset.stats.size; } - } + // needs to add test case where shared bundle is removed from ONE bundlegroup but not from the whole graph! + // Remove the edge from this bundle group to the shared bundle. + // If there is now only a single bundle group that contains this bundle, + // merge it into the remaining source bundles. If it is orphaned entirely, remove it. + let incomingNodeCount = + bundleGraph.getNodeIdsConnectedTo(bundleIdToRemove).length; - // Remove the edge from this bundle group to the shared bundle. - bundleGraph.removeEdge(bundleGroupId, bundleIdToRemove); - - // If there is now only a single bundle group that contains this bundle, - // merge it into the remaining source bundles. If it is orphaned entirely, remove it. - let incomingNodeCount = - bundleGraph.getNodeIdsConnectedTo(bundleIdToRemove).length; - if (incomingNodeCount === 1) { - removeBundle(bundleGraph, bundleIdToRemove, assetReference); - for (let sharedBundleId of sharedToSourceBundleIds.keys()) { - if (sharedBundleId === bundleIdToRemove) { - sharedToSourceBundleIds.delete(sharedBundleId); - } + if ( + incomingNodeCount <= 2 && + //Never fully remove reused bundles + bundleToRemove.mainEntryAsset == null + ) { + // If one bundle group removes a shared bundle, but the other *can* keep it, still remove because that shared bundle is pointless (only one source bundle) + removeBundle(bundleGraph, bundleIdToRemove, assetReference); + } else { + bundleGraph.removeEdge(sourceBundleId, bundleIdToRemove); } - } else if (incomingNodeCount === 0) { - bundleGraph.removeNode(bundleIdToRemove); } + numBundlesInGroup--; } } } @@ -1100,7 +1105,7 @@ function createIdealGraph( bundleGraph.traverseAncestors(nodeId, ancestorId => { if ( bundleGraph - .getNodeIdsConnectedTo(ancestorId) + .getNodeIdsConnectedTo(ancestorId) //if node is root, then dont add, otherwise do add. .includes(bundleGraph.rootNodeId) ) { bundleGroupBundleIds.add(ancestorId); @@ -1108,6 +1113,13 @@ function createIdealGraph( }); return bundleGroupBundleIds; } + function getBundlesForBundleGroup(bundleGroupId) { + let bundlesInABundleGroup = []; + bundleGraph.traverse(nodeId => { + bundlesInABundleGroup.push(nodeId); + }, bundleGroupId); + return bundlesInABundleGroup; + } function mergeBundle(mainNodeId: NodeId, otherNodeId: NodeId) { //merges assets of "otherRoot" into "mainBundleRoot" @@ -1155,7 +1167,6 @@ function createIdealGraph( dependencyBundleGraph, bundleGroupBundleIds, assetReference, - sharedToSourceBundleIds, }; } @@ -1195,7 +1206,7 @@ function createBundle(opts: {| internalizedAssetIds: [], mainEntryAsset: null, size: 0, - sourceBundles: [], + sourceBundles: new Set(), target: opts.target, type: nullthrows(opts.type), env: nullthrows(opts.env), @@ -1211,7 +1222,7 @@ function createBundle(opts: {| internalizedAssetIds: [], mainEntryAsset: asset, size: asset.stats.size, - sourceBundles: [], + sourceBundles: new Set(), target: opts.target, type: opts.type ?? asset.type, env: opts.env ?? asset.env, diff --git a/packages/core/integration-tests/test/bundler.js b/packages/core/integration-tests/test/bundler.js index 13c1cca56f9..72028f9d773 100644 --- a/packages/core/integration-tests/test/bundler.js +++ b/packages/core/integration-tests/test/bundler.js @@ -1,108 +1,152 @@ -import assert from 'assert'; -import sinon from 'sinon'; import path from 'path'; -import { - assertBundleTree, - bundle, - bundler, - nextBundle, -} from '@parcel/test-utils'; +import {bundle, assertBundles} from '@parcel/test-utils'; -describe.skip('bundler', function () { - it('should bundle once before exporting middleware', async function () { - let b = bundler( - path.join(__dirname, '/integration/bundler-middleware/index.js'), +describe('bundler', function () { + it('should remove reused bundle (over shared bundles based on size) if the bundlegroup hit the parallel request limit', async function () { + let b = await bundle( + path.join( + __dirname, + 'integration/shared-bundle-reused-bundle-remove-reuse/index.js', + ), + { + mode: 'production', + defaultTargetOptions: { + shouldScopeHoist: false, + }, + }, ); - b.middleware(); - - await nextBundle(b); - assert(b.entryAssets); - }); - - it('should defer bundling if a bundle is pending', async () => { - const b = bundler(path.join(__dirname, '/integration/html/index.html')); - b.pending = true; // bundle in progress - const spy = sinon.spy(b, 'bundle'); - - // first bundle, with existing bundle pending - const bundlePromise = b.bundle(); - - // simulate bundle finished - b.pending = false; - b.emit('buildEnd'); - - // wait for bundle to complete - await bundlePromise; - - assert(spy.calledTwice); - }); - - it('should enforce asset type path to be a string', () => { - const b = bundler(path.join(__dirname, '/integration/html/index.html')); - - assert.throws(() => { - b.addAssetType('.ext', {}); - }, 'should be a module path'); - }); - - it('should enforce setup before bundling', () => { - const b = bundler(path.join(__dirname, '/integration/html/index.html')); - b.farm = true; // truthy - assert.throws(() => { - b.addAssetType('.ext', __filename); - }, 'before bundling'); - - assert.throws(() => { - b.addPackager('type', 'packager'); - }, 'before bundling'); + assertBundles(b, [ + { + name: 'index.js', + assets: [ + 'index.js', + 'bundle-url.js', + 'cacheLoader.js', + 'css-loader.js', + 'esmodule-helpers.js', + 'js-loader.js', + 'bundle-manifest.js', + ], + }, + { + assets: ['bar.js', 'foo.js', 'a.js', 'b.js'], + }, + { + assets: ['buzz.js'], + }, + { + assets: ['c.js'], + }, + { + assets: ['a.js', 'b.js', 'foo.js'], + }, + { + assets: ['styles.css'], + }, + { + assets: ['local.html'], + }, + ]); }); - it('should support multiple entry points', async function () { - let b = await bundle([ - path.join(__dirname, '/integration/multi-entry/one.html'), - path.join(__dirname, '/integration/multi-entry/two.html'), - ]); + //This test case is the sdame as previous except we remove the shared bundle since it is smaller + it('should remove shared bundle (over reused bundles based on size) if the bundlegroup hit the parallel request limit', async function () { + let b = await bundle( + path.join( + __dirname, + 'integration/shared-bundle-reused-bundle-remove-shared/index.js', + ), + { + mode: 'production', + defaultTargetOptions: { + shouldScopeHoist: false, + }, + }, + ); - await assertBundleTree(b, [ - { - type: 'html', - assets: ['one.html'], - childBundles: [ - { - type: 'js', - assets: ['shared.js'], - }, + assertBundles(b, [ + { + name: 'index.js', + assets: [ + 'index.js', + 'bundle-url.js', + 'cacheLoader.js', + 'css-loader.js', + 'esmodule-helpers.js', + 'js-loader.js', + 'bundle-manifest.js', ], }, { - type: 'html', - assets: ['two.html'], - childBundles: [], + assets: ['bar.js', 'c.js'], + }, + { + // A consequence of our shared bundle 'c' being removed for the bundleGroup bar + // is that it must also be removed for buzz, even though the buzz bundleGroup does not + // hit the parallel request limit. This is because the shared bundle is no longer sharing + // it is only attached to one bundle and thus should be removed. + assets: ['buzz.js', 'c.js'], + }, + { + assets: ['a.js', 'b.js', 'foo.js'], + }, + { + assets: ['styles.css'], + }, + { + assets: ['local.html'], }, ]); }); - it('should support multiple entry points as a glob', async function () { + it('should not remove shared bundle from graph if one bundlegroup hits the parallel request limit, and at least 2 other bundleGroups that need it do not', async function () { + //The shared bundle should only be 'put back' for the bundlegroups which hit the parallel request limit + // But if there are at least two other bundlegroups using this shared bundle that do not hit the max limit + // the shared bundle should not be removed from the graph let b = await bundle( - path.join(__dirname, '/integration/multi-entry/*.html'), + path.join( + __dirname, + 'integration/shared-bundle-remove-from-one-group-only/index.js', + ), + { + mode: 'production', + defaultTargetOptions: { + shouldScopeHoist: false, + }, + }, ); - await assertBundleTree(b, [ - { - type: 'html', - assets: ['one.html'], - childBundles: [ - { - type: 'js', - assets: ['shared.js'], - }, + assertBundles(b, [ + { + name: 'index.js', + assets: [ + 'index.js', + 'bundle-url.js', + 'cacheLoader.js', + 'css-loader.js', + 'esmodule-helpers.js', + 'js-loader.js', + 'bundle-manifest.js', ], }, { - type: 'html', - assets: ['two.html'], - childBundles: [], + assets: ['bar.js', 'c.js'], // shared bundle merged back + }, + { + assets: ['buzz.js'], + }, + { + assets: ['c.js'], // shared bundle + }, + { + assets: ['foo.js'], + }, + { + assets: ['styles.css'], + }, + { + assets: ['local.html'], }, ]); }); diff --git a/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/bar.js b/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/bar.js new file mode 100644 index 00000000000..6aa9dc65b2d --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/bar.js @@ -0,0 +1,5 @@ +import styles from './styles.css'; +import html from './local.html'; +import c from './c'; + +export default 4; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/buzz.js b/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/buzz.js new file mode 100644 index 00000000000..150df2b16bc --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/buzz.js @@ -0,0 +1 @@ +import c from './c'; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/c.js b/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/c.js new file mode 100644 index 00000000000..cb6dc8ff662 --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/c.js @@ -0,0 +1,7 @@ +let str = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras euismod massa sit amet tellus porta consectetur. Etiam aliquam pellentesque lorem id semper. Vestibulum ut rhoncus lacus, a blandit risus. Sed eget volutpat risus, eu molestie mi. Curabitur felis lacus, hendrerit id sollicitudin nec, sollicitudin in quam. Nunc pellentesque elit ac sapien tempor feugiat. Nunc ex urna, commodo in viverra a, tempus quis purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; +Pellentesque pharetra mauris luctus felis cursus, id tempor sem viverra. Aenean fringilla, felis ut feugiat pretium, sapien lectus ornare enim, vel tempus mi tortor vitae lectus. Sed egestas mollis massa in dignissim. Sed placerat tellus id ligula molestie, id tincidunt sem rutrum. Aliquam erat volutpat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam est purus, maximus ut mi id, pharetra dictum lacus. Praesent ullamcorper libero metus, id ornare ex posuere ac. Ut tempor varius molestie. Sed a turpis lobortis, pretium leo ut, tempus turpis. Curabitur blandit ligula in mi pretium, sed varius libero tempus. Nunc pellentesque odio metus, vitae commodo neque eleifend ac. +Cras et est suscipit, suscipit dolor nec, blandit leo. Donec purus neque, rhoncus ac ullamcorper eget, placerat vel magna. Donec eu augue turpis. Fusce mattis nulla ante. Proin sit amet sem maximus, pharetra tortor et, sollicitudin eros. Curabitur elementum dolor ac metus vulputate ornare. Ut arcu libero, lobortis ac urna ut, ornare laoreet tortor. Vivamus sollicitudin suscipit efficitur. Ut nec nisi sed metus blandit bibendum. Nullam dictum accumsan sem, ac aliquam purus vestibulum sed. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut et ligula eget magna tempus interdum. Aliquam malesuada tempus imperdiet. Proin et elementum tellus, non aliquam magna. Sed id felis ut arcu aliquam aliquam eu nec nisi. +Donec dictum consequat quam nec malesuada. Nunc mattis iaculis vestibulum. Vestibulum erat lacus, mollis et tincidunt sit amet, tristique vitae massa. Phasellus ac vulputate dolor. Pellentesque ac auctor metus, nec faucibus erat. Donec tortor neque, convallis non felis vel, posuere ornare nunc. Fusce magna risus, interdum at pretium vel, finibus ut dolor. Vivamus congue ipsum non cursus tristique. Suspendisse in nulla accumsan, volutpat turpis eu, gravida sapien. Nam commodo velit vel tellus ultricies, ut consectetur neque molestie. Praesent tincidunt, libero ac elementum luctus, ex nisi volutpat leo, a hendrerit lacus leo eget tortor. Suspendisse viverra ante sit amet accumsan facilisis. Pellentesque velit nisl, luctus bibendum vulputate eget, dapibus at elit. Nam ac molestie turpis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Fusce cursus, magna non viverra rutrum, magna metus blandit tortor, sed elementum tellus lectus at velit. +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Morbi sollicitudin scelerisque sagittis. Cras mattis dictum sollicitudin. Donec tincidunt ullamcorper elit, non dignissim nulla ornare ac. Nulla at interdum nisl. Cras eget tincidunt neque. Etiam lobortis sem iaculis, accumsan augue vel, condimentum sem. Mauris porta congue nulla, id congue eros. Nullam nec arcu in ante elementum blandit sit amet ac nibh. Fusce eget risus tincidunt, viverra neque quis, pellentesque est. Sed et nisi nec massa consequat commodo pretium nec risus. Maecenas vestibulum diam ex, sit amet maximus lacus luctus scelerisque. Mauris eget ante sollicitudin, commodo purus eu, molestie tellus. Aliquam finibus eros nisi, eu cursus sapien pellentesque in. Cras eget justo tincidunt, congue lorem eu, dignissim metus.`; + +export default 'c'; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/foo.js b/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/foo.js new file mode 100644 index 00000000000..cd8b62f02a4 --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/foo.js @@ -0,0 +1,3 @@ +import c from './c'; + +export default a; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/index.js b/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/index.js new file mode 100644 index 00000000000..14be3f87ce4 --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/index.js @@ -0,0 +1,5 @@ +import('./foo'); +import('./bar'); +import('./buzz'); + +export default 1; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/local.html b/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/local.html new file mode 100644 index 00000000000..e1fd3f4ed29 --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/local.html @@ -0,0 +1,6 @@ + + + + Hello World + + diff --git a/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/package.json b/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/package.json new file mode 100644 index 00000000000..b33fbed8758 --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/package.json @@ -0,0 +1,6 @@ +{ + "@parcel/bundler-default": { + "minBundleSize": 200, + "maxParallelRequests":2 + } +} diff --git a/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/styles.css b/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/styles.css new file mode 100644 index 00000000000..c423315142e --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/styles.css @@ -0,0 +1 @@ +p.groove {outline-style: groove;} diff --git a/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/yarn.lock b/packages/core/integration-tests/test/integration/shared-bundle-remove-from-one-group-only/yarn.lock new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/a.js b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/a.js new file mode 100644 index 00000000000..5338612bd6f --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/a.js @@ -0,0 +1,3 @@ +import foo from './foo'; + +export default 'a'; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/b.js b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/b.js new file mode 100644 index 00000000000..12bcbe2c3eb --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/b.js @@ -0,0 +1,2 @@ + +export default 5; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/bar.js b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/bar.js new file mode 100644 index 00000000000..d091ccd0ead --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/bar.js @@ -0,0 +1,7 @@ +import foo from './a'; +import bar from './b'; +import styles from './styles.css'; +import html from './local.html'; +import c from './c'; + +export default 4; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/buzz.js b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/buzz.js new file mode 100644 index 00000000000..150df2b16bc --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/buzz.js @@ -0,0 +1 @@ +import c from './c'; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/c.js b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/c.js new file mode 100644 index 00000000000..cb6dc8ff662 --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/c.js @@ -0,0 +1,7 @@ +let str = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras euismod massa sit amet tellus porta consectetur. Etiam aliquam pellentesque lorem id semper. Vestibulum ut rhoncus lacus, a blandit risus. Sed eget volutpat risus, eu molestie mi. Curabitur felis lacus, hendrerit id sollicitudin nec, sollicitudin in quam. Nunc pellentesque elit ac sapien tempor feugiat. Nunc ex urna, commodo in viverra a, tempus quis purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; +Pellentesque pharetra mauris luctus felis cursus, id tempor sem viverra. Aenean fringilla, felis ut feugiat pretium, sapien lectus ornare enim, vel tempus mi tortor vitae lectus. Sed egestas mollis massa in dignissim. Sed placerat tellus id ligula molestie, id tincidunt sem rutrum. Aliquam erat volutpat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam est purus, maximus ut mi id, pharetra dictum lacus. Praesent ullamcorper libero metus, id ornare ex posuere ac. Ut tempor varius molestie. Sed a turpis lobortis, pretium leo ut, tempus turpis. Curabitur blandit ligula in mi pretium, sed varius libero tempus. Nunc pellentesque odio metus, vitae commodo neque eleifend ac. +Cras et est suscipit, suscipit dolor nec, blandit leo. Donec purus neque, rhoncus ac ullamcorper eget, placerat vel magna. Donec eu augue turpis. Fusce mattis nulla ante. Proin sit amet sem maximus, pharetra tortor et, sollicitudin eros. Curabitur elementum dolor ac metus vulputate ornare. Ut arcu libero, lobortis ac urna ut, ornare laoreet tortor. Vivamus sollicitudin suscipit efficitur. Ut nec nisi sed metus blandit bibendum. Nullam dictum accumsan sem, ac aliquam purus vestibulum sed. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut et ligula eget magna tempus interdum. Aliquam malesuada tempus imperdiet. Proin et elementum tellus, non aliquam magna. Sed id felis ut arcu aliquam aliquam eu nec nisi. +Donec dictum consequat quam nec malesuada. Nunc mattis iaculis vestibulum. Vestibulum erat lacus, mollis et tincidunt sit amet, tristique vitae massa. Phasellus ac vulputate dolor. Pellentesque ac auctor metus, nec faucibus erat. Donec tortor neque, convallis non felis vel, posuere ornare nunc. Fusce magna risus, interdum at pretium vel, finibus ut dolor. Vivamus congue ipsum non cursus tristique. Suspendisse in nulla accumsan, volutpat turpis eu, gravida sapien. Nam commodo velit vel tellus ultricies, ut consectetur neque molestie. Praesent tincidunt, libero ac elementum luctus, ex nisi volutpat leo, a hendrerit lacus leo eget tortor. Suspendisse viverra ante sit amet accumsan facilisis. Pellentesque velit nisl, luctus bibendum vulputate eget, dapibus at elit. Nam ac molestie turpis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Fusce cursus, magna non viverra rutrum, magna metus blandit tortor, sed elementum tellus lectus at velit. +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Morbi sollicitudin scelerisque sagittis. Cras mattis dictum sollicitudin. Donec tincidunt ullamcorper elit, non dignissim nulla ornare ac. Nulla at interdum nisl. Cras eget tincidunt neque. Etiam lobortis sem iaculis, accumsan augue vel, condimentum sem. Mauris porta congue nulla, id congue eros. Nullam nec arcu in ante elementum blandit sit amet ac nibh. Fusce eget risus tincidunt, viverra neque quis, pellentesque est. Sed et nisi nec massa consequat commodo pretium nec risus. Maecenas vestibulum diam ex, sit amet maximus lacus luctus scelerisque. Mauris eget ante sollicitudin, commodo purus eu, molestie tellus. Aliquam finibus eros nisi, eu cursus sapien pellentesque in. Cras eget justo tincidunt, congue lorem eu, dignissim metus.`; + +export default 'c'; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/foo.js b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/foo.js new file mode 100644 index 00000000000..25e39b4904f --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/foo.js @@ -0,0 +1,4 @@ +import a from './a'; +import b from './b'; + +export default a; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/index.js b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/index.js new file mode 100644 index 00000000000..14be3f87ce4 --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/index.js @@ -0,0 +1,5 @@ +import('./foo'); +import('./bar'); +import('./buzz'); + +export default 1; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/local.html b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/local.html new file mode 100644 index 00000000000..e1fd3f4ed29 --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/local.html @@ -0,0 +1,6 @@ + + + + Hello World + + diff --git a/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/package.json b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/package.json new file mode 100644 index 00000000000..d94483f52b6 --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/package.json @@ -0,0 +1,6 @@ +{ + "@parcel/bundler-default": { + "minBundleSize": 200, + "maxParallelRequests":3 + } +} diff --git a/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/styles.css b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/styles.css new file mode 100644 index 00000000000..c423315142e --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/styles.css @@ -0,0 +1 @@ +p.groove {outline-style: groove;} diff --git a/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/yarn.lock b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-reuse/yarn.lock new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/a.js b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/a.js new file mode 100644 index 00000000000..bdfb65d56c7 --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/a.js @@ -0,0 +1,9 @@ +import foo from './foo'; + +let str = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras euismod massa sit amet tellus porta consectetur. Etiam aliquam pellentesque lorem id semper. Vestibulum ut rhoncus lacus, a blandit risus. Sed eget volutpat risus, eu molestie mi. Curabitur felis lacus, hendrerit id sollicitudin nec, sollicitudin in quam. Nunc pellentesque elit ac sapien tempor feugiat. Nunc ex urna, commodo in viverra a, tempus quis purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; +Pellentesque pharetra mauris luctus felis cursus, id tempor sem viverra. Aenean fringilla, felis ut feugiat pretium, sapien lectus ornare enim, vel tempus mi tortor vitae lectus. Sed egestas mollis massa in dignissim. Sed placerat tellus id ligula molestie, id tincidunt sem rutrum. Aliquam erat volutpat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam est purus, maximus ut mi id, pharetra dictum lacus. Praesent ullamcorper libero metus, id ornare ex posuere ac. Ut tempor varius molestie. Sed a turpis lobortis, pretium leo ut, tempus turpis. Curabitur blandit ligula in mi pretium, sed varius libero tempus. Nunc pellentesque odio metus, vitae commodo neque eleifend ac. +Cras et est suscipit, suscipit dolor nec, blandit leo. Donec purus neque, rhoncus ac ullamcorper eget, placerat vel magna. Donec eu augue turpis. Fusce mattis nulla ante. Proin sit amet sem maximus, pharetra tortor et, sollicitudin eros. Curabitur elementum dolor ac metus vulputate ornare. Ut arcu libero, lobortis ac urna ut, ornare laoreet tortor. Vivamus sollicitudin suscipit efficitur. Ut nec nisi sed metus blandit bibendum. Nullam dictum accumsan sem, ac aliquam purus vestibulum sed. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut et ligula eget magna tempus interdum. Aliquam malesuada tempus imperdiet. Proin et elementum tellus, non aliquam magna. Sed id felis ut arcu aliquam aliquam eu nec nisi. +Donec dictum consequat quam nec malesuada. Nunc mattis iaculis vestibulum. Vestibulum erat lacus, mollis et tincidunt sit amet, tristique vitae massa. Phasellus ac vulputate dolor. Pellentesque ac auctor metus, nec faucibus erat. Donec tortor neque, convallis non felis vel, posuere ornare nunc. Fusce magna risus, interdum at pretium vel, finibus ut dolor. Vivamus congue ipsum non cursus tristique. Suspendisse in nulla accumsan, volutpat turpis eu, gravida sapien. Nam commodo velit vel tellus ultricies, ut consectetur neque molestie. Praesent tincidunt, libero ac elementum luctus, ex nisi volutpat leo, a hendrerit lacus leo eget tortor. Suspendisse viverra ante sit amet accumsan facilisis. Pellentesque velit nisl, luctus bibendum vulputate eget, dapibus at elit. Nam ac molestie turpis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Fusce cursus, magna non viverra rutrum, magna metus blandit tortor, sed elementum tellus lectus at velit. +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Morbi sollicitudin scelerisque sagittis. Cras mattis dictum sollicitudin. Donec tincidunt ullamcorper elit, non dignissim nulla ornare ac. Nulla at interdum nisl. Cras eget tincidunt neque. Etiam lobortis sem iaculis, accumsan augue vel, condimentum sem. Mauris porta congue nulla, id congue eros. Nullam nec arcu in ante elementum blandit sit amet ac nibh. Fusce eget risus tincidunt, viverra neque quis, pellentesque est. Sed et nisi nec massa consequat commodo pretium nec risus. Maecenas vestibulum diam ex, sit amet maximus lacus luctus scelerisque. Mauris eget ante sollicitudin, commodo purus eu, molestie tellus. Aliquam finibus eros nisi, eu cursus sapien pellentesque in. Cras eget justo tincidunt, congue lorem eu, dignissim metus.`; + +export default 'a'; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/b.js b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/b.js new file mode 100644 index 00000000000..c2f27c9f6ff --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/b.js @@ -0,0 +1,7 @@ +let str = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras euismod massa sit amet tellus porta consectetur. Etiam aliquam pellentesque lorem id semper. Vestibulum ut rhoncus lacus, a blandit risus. Sed eget volutpat risus, eu molestie mi. Curabitur felis lacus, hendrerit id sollicitudin nec, sollicitudin in quam. Nunc pellentesque elit ac sapien tempor feugiat. Nunc ex urna, commodo in viverra a, tempus quis purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; +Pellentesque pharetra mauris luctus felis cursus, id tempor sem viverra. Aenean fringilla, felis ut feugiat pretium, sapien lectus ornare enim, vel tempus mi tortor vitae lectus. Sed egestas mollis massa in dignissim. Sed placerat tellus id ligula molestie, id tincidunt sem rutrum. Aliquam erat volutpat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam est purus, maximus ut mi id, pharetra dictum lacus. Praesent ullamcorper libero metus, id ornare ex posuere ac. Ut tempor varius molestie. Sed a turpis lobortis, pretium leo ut, tempus turpis. Curabitur blandit ligula in mi pretium, sed varius libero tempus. Nunc pellentesque odio metus, vitae commodo neque eleifend ac. +Cras et est suscipit, suscipit dolor nec, blandit leo. Donec purus neque, rhoncus ac ullamcorper eget, placerat vel magna. Donec eu augue turpis. Fusce mattis nulla ante. Proin sit amet sem maximus, pharetra tortor et, sollicitudin eros. Curabitur elementum dolor ac metus vulputate ornare. Ut arcu libero, lobortis ac urna ut, ornare laoreet tortor. Vivamus sollicitudin suscipit efficitur. Ut nec nisi sed metus blandit bibendum. Nullam dictum accumsan sem, ac aliquam purus vestibulum sed. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut et ligula eget magna tempus interdum. Aliquam malesuada tempus imperdiet. Proin et elementum tellus, non aliquam magna. Sed id felis ut arcu aliquam aliquam eu nec nisi. +Donec dictum consequat quam nec malesuada. Nunc mattis iaculis vestibulum. Vestibulum erat lacus, mollis et tincidunt sit amet, tristique vitae massa. Phasellus ac vulputate dolor. Pellentesque ac auctor metus, nec faucibus erat. Donec tortor neque, convallis non felis vel, posuere ornare nunc. Fusce magna risus, interdum at pretium vel, finibus ut dolor. Vivamus congue ipsum non cursus tristique. Suspendisse in nulla accumsan, volutpat turpis eu, gravida sapien. Nam commodo velit vel tellus ultricies, ut consectetur neque molestie. Praesent tincidunt, libero ac elementum luctus, ex nisi volutpat leo, a hendrerit lacus leo eget tortor. Suspendisse viverra ante sit amet accumsan facilisis. Pellentesque velit nisl, luctus bibendum vulputate eget, dapibus at elit. Nam ac molestie turpis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Fusce cursus, magna non viverra rutrum, magna metus blandit tortor, sed elementum tellus lectus at velit. +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Morbi sollicitudin scelerisque sagittis. Cras mattis dictum sollicitudin. Donec tincidunt ullamcorper elit, non dignissim nulla ornare ac. Nulla at interdum nisl. Cras eget tincidunt neque. Etiam lobortis sem iaculis, accumsan augue vel, condimentum sem. Mauris porta congue nulla, id congue eros. Nullam nec arcu in ante elementum blandit sit amet ac nibh. Fusce eget risus tincidunt, viverra neque quis, pellentesque est. Sed et nisi nec massa consequat commodo pretium nec risus. Maecenas vestibulum diam ex, sit amet maximus lacus luctus scelerisque. Mauris eget ante sollicitudin, commodo purus eu, molestie tellus. Aliquam finibus eros nisi, eu cursus sapien pellentesque in. Cras eget justo tincidunt, congue lorem eu, dignissim metus.`; + +export default 5; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/bar.js b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/bar.js new file mode 100644 index 00000000000..d091ccd0ead --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/bar.js @@ -0,0 +1,7 @@ +import foo from './a'; +import bar from './b'; +import styles from './styles.css'; +import html from './local.html'; +import c from './c'; + +export default 4; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/buzz.js b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/buzz.js new file mode 100644 index 00000000000..150df2b16bc --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/buzz.js @@ -0,0 +1 @@ +import c from './c'; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/c.js b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/c.js new file mode 100644 index 00000000000..e15fcf78ebd --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/c.js @@ -0,0 +1,7 @@ +let str = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras euismod massa sit amet tellus porta consectetur. Etiam aliquam pellentesque lorem id semper. Vestibulum ut rhoncus lacus, a blandit risus. Sed eget volutpat risus, eu molestie mi. Curabitur felis lacus, hendrerit id sollicitudin nec, sollicitudin in quam. Nunc pellentesque elit ac sapien tempor feugiat. Nunc ex urna, commodo in viverra a, tempus quis purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; +Pellentesque pharetra mauris luctus felis cursus, id tempor sem viverra. Aenean fringilla, felis ut feugiat pretium, sapien lectus ornare enim, vel tempus mi tortor vitae lectus. Sed egestas mollis massa in dignissim. Sed placerat tellus id ligula molestie, id tincidunt sem rutrum. Aliquam erat volutpat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam est purus, maximus ut mi id, pharetra dictum lacus. Praesent ullamcorper libero metus, id ornare ex posuere ac. Ut tempor varius molestie. Sed a turpis lobortis, pretium leo ut, tempus turpis. Curabitur blandit ligula in mi pretium, sed varius libero tempus. Nunc pellentesque odio metus, vitae commodo neque eleifend ac. +Cras et est suscipit, suscipit dolor nec, blandit leo. Donec purus neque, rhoncus ac ullamcorper eget, placerat vel magna. Donec eu augue turpis. Fusce mattis nulla ante. Proin sit amet sem maximus, pharetra tortor et, sollicitudin eros. Curabitur elementum dolor ac metus vulputate ornare. Ut arcu libero, lobortis ac urna ut, ornare laoreet tortor. Vivamus sollicitudin suscipit efficitur. Ut nec nisi sed metus blandit bibendum. Nullam dictum accumsan sem, ac aliquam purus vestibulum sed. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut et ligula eget magna tempus interdum. Aliquam malesuada tempus imperdiet. Proin et elementum tellus, non aliquam magna. Sed id felis ut arcu aliquam aliquam eu nec nisi. +Donec dictum consequat quam nec malesuada. Nunc mattis iaculis vestibulum. Vestibulum erat lacus, mollis et tincidunt sit amet, tristique vitae massa. Phasellus ac vulputate dolor. Pellentesque ac auctor metus, nec faucibus erat. Donec tortor neque, convallis non felis vel, posuere ornare nunc. Fusce magna risus, interdum at pretium vel, finibus ut dolor. Vivamus congue ipsum non cursus tristique. Suspendisse in nulla accumsan, volutpat turpis eu, gravida sapien. Nam commodo velit vel tellus ultricies, ut consectetur neque molestie. Praesent tincidunt, libero ac elementum luctus, ex nisi volutpat leo, a hendrerit lacus leo eget tortor. Suspendisse viverra ante sit amet accumsan facilisis. Pellentesque velit nisl, luctus bibendum vulputate eget, dapibus at elit. Nam ac molestie turpis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Fusce cursus, magna non viverra rutrum, magna metus blandit tortor, sed elementum tellus lectus at velit. +Pellentesque morbi tristique senectus et netus et malesuada fames ac turpis egestas. Morbi sollicitudin scelerisque sagittis. Cras mattis dictum sollicitudin. Donec tincidunt ullamcorper elit, non dignissim nulla ornare ac. Nulla at interdum nisl. Cras eget tincidunt neque. Etiam lobortis sem iaculis, accumsan augue vel, condimentum sem. Mauris porta congue nulla, id congue eros. Nullam nec arcu in ante elementum blandit sit amet ac nibh. Fusce eget risus tincidunt, viverra neque quis, pellentesque est. Sed et nisi nec massa consequat commodo pretium nec risus. Maecenas vestibulum diam ex, sit amet maximus lacus luctus scelerisque. Mauris eget ante sollicitudin, commodo purus eu, molestie tellus. Aliquam finibus eros nisi, eu cursus sapien pellentesque in. Cras eget justo tincidunt, congue lorem eu, dignissim metus.`; + +export default 'c'; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/foo.js b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/foo.js new file mode 100644 index 00000000000..25e39b4904f --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/foo.js @@ -0,0 +1,4 @@ +import a from './a'; +import b from './b'; + +export default a; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/index.js b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/index.js new file mode 100644 index 00000000000..14be3f87ce4 --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/index.js @@ -0,0 +1,5 @@ +import('./foo'); +import('./bar'); +import('./buzz'); + +export default 1; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/local.html b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/local.html new file mode 100644 index 00000000000..e1fd3f4ed29 --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/local.html @@ -0,0 +1,6 @@ + + + + Hello World + + diff --git a/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/package.json b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/package.json new file mode 100644 index 00000000000..d94483f52b6 --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/package.json @@ -0,0 +1,6 @@ +{ + "@parcel/bundler-default": { + "minBundleSize": 200, + "maxParallelRequests":3 + } +} diff --git a/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/styles.css b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/styles.css new file mode 100644 index 00000000000..c423315142e --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/styles.css @@ -0,0 +1 @@ +p.groove {outline-style: groove;} diff --git a/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/yarn.lock b/packages/core/integration-tests/test/integration/shared-bundle-reused-bundle-remove-shared/yarn.lock new file mode 100644 index 00000000000..e69de29bb2d From 74e8719e759dcdc3ba144d6996e5e49790de76f8 Mon Sep 17 00:00:00 2001 From: Agnieszka Gawrys Date: Tue, 12 Jul 2022 13:51:30 -0400 Subject: [PATCH 02/10] do not consider reuse bundles for min size removal as it breaks build --- packages/bundlers/experimental/src/ExperimentalBundler.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/bundlers/experimental/src/ExperimentalBundler.js b/packages/bundlers/experimental/src/ExperimentalBundler.js index 9a5b06a0d39..d2f2d9f3246 100644 --- a/packages/bundlers/experimental/src/ExperimentalBundler.js +++ b/packages/bundlers/experimental/src/ExperimentalBundler.js @@ -1001,7 +1001,11 @@ function createIdealGraph( // We should include "bundle reuse" as shared bundles that may be removed but the bundle itself would have to be retained for (let [bundleNodeId, bundle] of bundleGraph.nodes) { if (bundle === 'root') continue; - if (bundle.sourceBundles.size > 0 && bundle.size < config.minBundleSize) { + if ( + bundle.sourceBundles.size > 0 && + bundle.mainEntryAsset == null && + bundle.size < config.minBundleSize + ) { removeBundle(bundleGraph, bundleNodeId, assetReference); } } From 655a1aa718c5be318f9455aaaab48f87d13ca2a5 Mon Sep 17 00:00:00 2001 From: Agnieszka Gawrys Date: Tue, 12 Jul 2022 16:19:06 -0400 Subject: [PATCH 03/10] rename reusing of bundles step and de fork test --- .../experimental/src/ExperimentalBundler.js | 75 +++++++++++-------- .../integration-tests/test/scope-hoisting.js | 4 +- 2 files changed, 45 insertions(+), 34 deletions(-) diff --git a/packages/bundlers/experimental/src/ExperimentalBundler.js b/packages/bundlers/experimental/src/ExperimentalBundler.js index d2f2d9f3246..f8550199dda 100644 --- a/packages/bundlers/experimental/src/ExperimentalBundler.js +++ b/packages/bundlers/experimental/src/ExperimentalBundler.js @@ -895,45 +895,58 @@ function createIdealGraph( // Finally, filter out bundleRoots (bundles) from this assets // reachable if they are subgraphs, and reuse that subgraph bundle - // by drawing an edge. Essentially, if two bundles within an assets + // by drawing an edge. Essentially, if two bundles within an asset's // reachable array, have an ancestor-subgraph relationship, draw that edge. // This allows for us to reuse a bundle instead of making a shared bundle if // a bundle represents the exact set of assets a set of bundles would share // if a bundle b is a subgraph of another bundle f, reuse it, drawing an edge between the two - reachable = reachable.filter(b => { - let bundleBid = nullthrows(bundles.get(b.id)); - if (b.env.isIsolated()) { - return true; - } - let toKeep = true; - if (bundles.has(asset.id)) { - let bundleRootBundleId = nullthrows(bundles.get(asset.id)); - toKeep = false; - bundleGraph.addEdge( - nullthrows(bundles.get(b.id)), - nullthrows(bundles.get(asset.id)), - ); - let bundleOfAsset = bundleGraph.getNode(bundleRootBundleId); - invariant(bundleOfAsset !== 'root' && bundleOfAsset != null); - bundleOfAsset.sourceBundles.add(bundleBid); + + let canReuse: Set = new Set(); + for (let candidateSourceBundleRoot of reachable) { + let candidateSourceBundleId = nullthrows( + bundles.get(candidateSourceBundleRoot.id), + ); + if (candidateSourceBundleRoot.env.isIsolated()) { + continue; } - for (let f of reachable) { - if (b === f) continue; - let fReachable = getReachableBundleRoots(f, reachableRoots).filter( - b => !ancestorAssets.get(b)?.has(f), - ); - if (fReachable.indexOf(b) > -1) { - let bundleFid = nullthrows(bundles.get(f.id)); - toKeep = false; - bundleGraph.addEdge(nullthrows(bundles.get(b.id)), bundleFid); - let bundleF = bundleGraph.getNode(bundleFid); - invariant(bundleF !== 'root' && bundleF != null); - bundleF.sourceBundles.add(bundleBid); + let reuseableBundleId = bundles.get(asset.id); + if (reuseableBundleId != null) { + canReuse.add(candidateSourceBundleRoot); + bundleGraph.addEdge(candidateSourceBundleId, reuseableBundleId); + + let reusableBundle = bundleGraph.getNode(reuseableBundleId); + invariant(reusableBundle !== 'root' && reusableBundle != null); + reusableBundle.sourceBundles.add(candidateSourceBundleId); + } else { + // Asset is not a bundleRoot, but if its parent bundle can be + // reused as a subgraph of another bundle in its reachable, reuse it + for (let otherReuseCandidate of reachable) { + if (candidateSourceBundleRoot === otherReuseCandidate) continue; + let reusableCandidateReachable = getReachableBundleRoots( + otherReuseCandidate, + reachableRoots, + ).filter(b => !ancestorAssets.get(b)?.has(otherReuseCandidate)); + if ( + reusableCandidateReachable.indexOf(candidateSourceBundleRoot) > -1 + ) { + let reusableBundleId = nullthrows( + bundles.get(otherReuseCandidate.id), + ); + canReuse.add(candidateSourceBundleRoot); + bundleGraph.addEdge( + nullthrows(bundles.get(candidateSourceBundleRoot.id)), + reusableBundleId, + ); + let reusableBundle = bundleGraph.getNode(reusableBundleId); + invariant(reusableBundle !== 'root' && reusableBundle != null); + reusableBundle.sourceBundles.add(candidateSourceBundleId); + } } } - return toKeep; - }); + } + //Bundles that are reused should not be considered for shared bundles, so filter them out + reachable = reachable.filter(b => !canReuse.has(b)); // Add assets to non-splittable bundles. for (let entry of reachableEntries) { diff --git a/packages/core/integration-tests/test/scope-hoisting.js b/packages/core/integration-tests/test/scope-hoisting.js index b1184cf9f27..2456b1f78fb 100644 --- a/packages/core/integration-tests/test/scope-hoisting.js +++ b/packages/core/integration-tests/test/scope-hoisting.js @@ -5193,9 +5193,7 @@ describe('scope hoisting', function () { }, {assets: ['dep.js']}, { - assets: process.env.PARCEL_TEST_EXPERIMENTAL_BUNDLER - ? ['async-has-dep.js'] - : ['async-has-dep.js', 'dep.js', 'get-dep.js'], + assets: ['async-has-dep.js', 'dep.js', 'get-dep.js'], }, {assets: ['get-dep.js']}, ]); From 7a06961216aecf8e504281e180188671878bf46b Mon Sep 17 00:00:00 2001 From: Agnieszka Gawrys Date: Tue, 12 Jul 2022 18:24:27 -0400 Subject: [PATCH 04/10] Handle case where rused bundle pulls in shared and then gets removed under parallel request limit --- .../experimental/src/ExperimentalBundler.js | 11 ++-- .../core/integration-tests/test/bundler.js | 60 ++++++++++++++++++- .../a.js | 3 + .../b.js | 2 + .../bar.js | 6 ++ .../buzz.js | 1 + .../c.js | 19 ++++++ .../foo.js | 4 ++ .../index.js | 5 ++ .../local.html | 6 ++ .../package.json | 6 ++ .../styles.css | 1 + .../yarn.lock | 0 13 files changed, 118 insertions(+), 6 deletions(-) create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/a.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/b.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/bar.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/buzz.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/c.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/foo.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/index.js create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/local.html create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/package.json create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/styles.css create mode 100644 packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/yarn.lock diff --git a/packages/bundlers/experimental/src/ExperimentalBundler.js b/packages/bundlers/experimental/src/ExperimentalBundler.js index f8550199dda..6f42b42a078 100644 --- a/packages/bundlers/experimental/src/ExperimentalBundler.js +++ b/packages/bundlers/experimental/src/ExperimentalBundler.js @@ -662,7 +662,6 @@ function createIdealGraph( if (assets.length === 0) { return; } - invariant(assets.length === 1); let bundleRoot = assets[0]; let bundle = nullthrows( @@ -706,7 +705,6 @@ function createIdealGraph( reachableRoots.addEdge(rootNodeId, nodeId); }, root); } - // Maps a given bundleRoot to the assets reachable from it, // and the bundleRoots reachable from each of these assets let ancestorAssets: Map> = new Map(); @@ -858,7 +856,6 @@ function createIdealGraph( deleteBundle(bundleRoot); } } - // Step Insert Or Share: Place all assets into bundles or create shared bundles. Each asset // is placed into a single bundle based on the bundle entries it is reachable from. // This creates a maximally code split bundle graph with no duplication. @@ -901,7 +898,6 @@ function createIdealGraph( // a bundle represents the exact set of assets a set of bundles would share // if a bundle b is a subgraph of another bundle f, reuse it, drawing an edge between the two - let canReuse: Set = new Set(); for (let candidateSourceBundleRoot of reachable) { let candidateSourceBundleId = nullthrows( @@ -1078,6 +1074,12 @@ function createIdealGraph( sourceBundle.assets.add(asset); sourceBundle.size += asset.stats.size; } + //This case is specific to reused bundles, which can have shared bundles attached to it + for (let childId of bundleGraph.getNodeIdsConnectedFrom( + bundleIdToRemove, + )) { + bundleGraph.addEdge(sourceBundleId, childId); + } // needs to add test case where shared bundle is removed from ONE bundlegroup but not from the whole graph! // Remove the edge from this bundle group to the shared bundle. // If there is now only a single bundle group that contains this bundle, @@ -1100,7 +1102,6 @@ function createIdealGraph( } } } - function deleteBundle(bundleRoot: BundleRoot) { bundleGraph.removeNode(nullthrows(bundles.get(bundleRoot.id))); bundleRoots.delete(bundleRoot); diff --git a/packages/core/integration-tests/test/bundler.js b/packages/core/integration-tests/test/bundler.js index 72028f9d773..0d4af73b31f 100644 --- a/packages/core/integration-tests/test/bundler.js +++ b/packages/core/integration-tests/test/bundler.js @@ -1,5 +1,6 @@ import path from 'path'; -import {bundle, assertBundles} from '@parcel/test-utils'; +import assert from 'assert'; +import {bundle, assertBundles, findAsset} from '@parcel/test-utils'; describe('bundler', function () { it('should remove reused bundle (over shared bundles based on size) if the bundlegroup hit the parallel request limit', async function () { @@ -150,4 +151,61 @@ describe('bundler', function () { }, ]); }); + + it.only('should not remove shared bundle from graph if its parent (a reused bundle) is removed by parallel request limit', async function () { + //The shared bundle should only be 'put back' for the bundlegroups which hit the parallel request limit + // But if there are at least two other bundlegroups using this shared bundle that do not hit the max limit + // the shared bundle should not be removed from the graph + let b = await bundle( + path.join( + __dirname, + 'integration/shared-bundle-between-reused-bundle-removal/index.js', + ), + { + mode: 'production', + defaultTargetOptions: { + shouldScopeHoist: false, + }, + }, + ); + + assertBundles(b, [ + { + name: 'index.js', + assets: [ + 'index.js', + 'bundle-url.js', + 'cacheLoader.js', + 'css-loader.js', + 'esmodule-helpers.js', + 'js-loader.js', + 'bundle-manifest.js', + ], + }, + { + assets: ['bar.js', 'foo.js', 'a.js', 'b.js'], // shared bundle merged back + }, + { + assets: ['buzz.js'], + }, + { + assets: ['c.js'], // shared bundle + }, + { + assets: ['foo.js', 'a.js', 'b.js'], + }, + { + assets: ['styles.css'], + }, + { + assets: ['local.html'], + }, + ]); + + assert( + b + .getReferencedBundles(b.getBundlesWithAsset(findAsset(b, 'bar.js'))[0]) + .includes(b.getBundlesWithAsset(findAsset(b, 'c.js'))[0]), + ); + }); }); diff --git a/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/a.js b/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/a.js new file mode 100644 index 00000000000..5338612bd6f --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/a.js @@ -0,0 +1,3 @@ +import foo from './foo'; + +export default 'a'; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/b.js b/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/b.js new file mode 100644 index 00000000000..12bcbe2c3eb --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/b.js @@ -0,0 +1,2 @@ + +export default 5; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/bar.js b/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/bar.js new file mode 100644 index 00000000000..401a5a4895d --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/bar.js @@ -0,0 +1,6 @@ +import foo from './a'; +import bar from './b'; +import styles from './styles.css'; +import html from './local.html'; + +export default 4; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/buzz.js b/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/buzz.js new file mode 100644 index 00000000000..150df2b16bc --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/buzz.js @@ -0,0 +1 @@ +import c from './c'; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/c.js b/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/c.js new file mode 100644 index 00000000000..22eadb2de17 --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/c.js @@ -0,0 +1,19 @@ +let str = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras euismod massa sit amet tellus porta consectetur. Etiam aliquam pellentesque lorem id semper. Vestibulum ut rhoncus lacus, a blandit risus. Sed eget volutpat risus, eu molestie mi. Curabitur felis lacus, hendrerit id sollicitudin nec, sollicitudin in quam. Nunc pellentesque elit ac sapien tempor feugiat. Nunc ex urna, commodo in viverra a, tempus quis purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; +Pellentesque pharetra mauris luctus felis cursus, id tempor sem viverra. Aenean fringilla, felis ut feugiat pretium, sapien lectus ornare enim, vel tempus mi tortor vitae lectus. Sed egestas mollis massa in dignissim. Sed placerat tellus id ligula molestie, id tincidunt sem rutrum. Aliquam erat volutpat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam est purus, maximus ut mi id, pharetra dictum lacus. Praesent ullamcorper libero metus, id ornare ex posuere ac. Ut tempor varius molestie. Sed a turpis lobortis, pretium leo ut, tempus turpis. Curabitur blandit ligula in mi pretium, sed varius libero tempus. Nunc pellentesque odio metus, vitae commodo neque eleifend ac. +Cras et est suscipit, suscipit dolor nec, blandit leo. Donec purus neque, rhoncus ac ullamcorper eget, placerat vel magna. Donec eu augue turpis. Fusce mattis nulla ante. Proin sit amet sem maximus, pharetra tortor et, sollicitudin eros. Curabitur elementum dolor ac metus vulputate ornare. Ut arcu libero, lobortis ac urna ut, ornare laoreet tortor. Vivamus sollicitudin suscipit efficitur. Ut nec nisi sed metus blandit bibendum. Nullam dictum accumsan sem, ac aliquam purus vestibulum sed. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut et ligula eget magna tempus interdum. Aliquam malesuada tempus imperdiet. Proin et elementum tellus, non aliquam magna. Sed id felis ut arcu aliquam aliquam eu nec nisi. +Donec dictum consequat quam nec malesuada. Nunc mattis iaculis vestibulum. Vestibulum erat lacus, mollis et tincidunt sit amet, tristique vitae massa. Phasellus ac vulputate dolor. Pellentesque ac auctor metus, nec faucibus erat. Donec tortor neque, convallis non felis vel, posuere ornare nunc. Fusce magna risus, interdum at pretium vel, finibus ut dolor. Vivamus congue ipsum non cursus tristique. Suspendisse in nulla accumsan, volutpat turpis eu, gravida sapien. Nam commodo velit vel tellus ultricies, ut consectetur neque molestie. Praesent tincidunt, libero ac elementum luctus, ex nisi volutpat leo, a hendrerit lacus leo eget tortor. Suspendisse viverra ante sit amet accumsan facilisis. Pellentesque velit nisl, luctus bibendum vulputate eget, dapibus at elit. Nam ac molestie turpis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Fusce cursus, magna non viverra rutrum, magna metus blandit tortor, sed elementum tellus lectus at velit. +Pellentesque habLorem ipsum dolor sit amet, consectetur adipiscing elit. Cras euismod massa sit amet tellus porta consectetur. Etiam aliquam pellentesque lorem id semper. Vestibulum ut rhoncus lacus, a blandit risus. Sed eget volutpat risus, eu molestie mi. Curabitur felis lacus, hendrerit id sollicitudin nec, sollicitudin in quam. Nunc pellentesque elit ac sapien tempor feugiat. Nunc ex urna, commodo in viverra a, tempus quis purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; +Pellentesque pharetra mauris luctus felis cursus, id tempor sem viverra. Aenean fringilla, felis ut feugiat pretium, sapien lectus ornare enim, vel tempus mi tortor vitae lectus. Sed egestas mollis massa in dignissim. Sed placerat tellus id ligula molestie, id tincidunt sem rutrum. Aliquam erat volutpat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam est purus, maximus ut mi id, pharetra dictum lacus. Praesent ullamcorper libero metus, id ornare ex posuere ac. Ut tempor varius molestie. Sed a turpis lobortis, pretium leo ut, tempus turpis. Curabitur blandit ligula in mi pretium, sed varius libero tempus. Nunc pellentesque odio metus, vitae commodo neque eleifend ac. +Cras et est suscipit, suscipit dolor nec, blandit leo. Donec purus neque, rhoncus ac ullamcorper eget, placerat vel magna. Donec eu augue turpis. Fusce mattis nulla ante. Proin sit amet sem maximus, pharetra tortor et, sollicitudin eros. Curabitur elementum dolor ac metus vulputate ornare. Ut arcu libero, lobortis ac urna ut, ornare laoreet tortor. Vivamus sollicitudin suscipit efficitur. Ut nec nisi sed metus blandit bibendum. Nullam dictum accumsan sem, ac aliquam purus vestibulum sed. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut et ligula eget magna tempus interdum. Aliquam malesuada tempus imperdiet. Proin et elementum tellus, non aliquam magna. Sed id felis ut arcu aliquam aliquam eu nec nisi. +Donec dictum consequat quam nec malesuada. Nunc mattis iaculis vestibulum. Vestibulum erat lacus, mollis et tincidunt sit amet, tristique vitae massa. Phasellus ac vulputate dolor. Pellentesque ac auctor metus, nec faucibus erat. Donec tortor neque, convallis non felis vel, posuere ornare nunc. Fusce magna risus, interdum at pretium vel, finibus ut dolor. Vivamus congue ipsum non cursus tristique. Suspendisse in nulla accumsan, volutpat turpis eu, gravida sapien. Nam commodo velit vel tellus ultricies, ut consectetur neque molestie. Praesent tincidunt, libero ac elementum luctus, ex nisi volutpat leo, a hendrerit lacus leo eget tortor. Suspendisse viverra ante sit amet accumsan facilisis. Pellentesque velit nisl, luctus bibendum vulputate eget, dapibus at elit. Nam ac molestie turpis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Fusce cursus, magna non viverra rutrum, magna metus blandit tortor, sed elementum tellus lectus at velit. +Pellentesque habLorem ipsum dolor sit amet, consectetur adipiscing elit. Cras euismod massa sit amet tellus porta consectetur. Etiam aliquam pellentesque lorem id semper. Vestibulum ut rhoncus lacus, a blandit risus. Sed eget volutpat risus, eu molestie mi. Curabitur felis lacus, hendrerit id sollicitudin nec, sollicitudin in quam. Nunc pellentesque elit ac sapien tempor feugiat. Nunc ex urna, commodo in viverra a, tempus quis purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; +Pellentesque pharetra mauris luctus felis cursus, id tempor sem viverra. Aenean fringilla, felis ut feugiat pretium, sapien lectus ornare enim, vel tempus mi tortor vitae lectus. Sed egestas mollis massa in dignissim. Sed placerat tellus id ligula molestie, id tincidunt sem rutrum. Aliquam erat volutpat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam est purus, maximus ut mi id, pharetra dictum lacus. Praesent ullamcorper libero metus, id ornare ex posuere ac. Ut tempor varius molestie. Sed a turpis lobortis, pretium leo ut, tempus turpis. Curabitur blandit ligula in mi pretium, sed varius libero tempus. Nunc pellentesque odio metus, vitae commodo neque eleifend ac. +Cras et est suscipit, suscipit dolor nec, blandit leo. Donec purus neque, rhoncus ac ullamcorper eget, placerat vel magna. Donec eu augue turpis. Fusce mattis nulla ante. Proin sit amet sem maximus, pharetra tortor et, sollicitudin eros. Curabitur elementum dolor ac metus vulputate ornare. Ut arcu libero, lobortis ac urna ut, ornare laoreet tortor. Vivamus sollicitudin suscipit efficitur. Ut nec nisi sed metus blandit bibendum. Nullam dictum accumsan sem, ac aliquam purus vestibulum sed. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut et ligula eget magna tempus interdum. Aliquam malesuada tempus imperdiet. Proin et elementum tellus, non aliquam magna. Sed id felis ut arcu aliquam aliquam eu nec nisi. +Donec dictum consequat quam nec malesuada. Nunc mattis iaculis vestibulum. Vestibulum erat lacus, mollis et tincidunt sit amet, tristique vitae massa. Phasellus ac vulputate dolor. Pellentesque ac auctor metus, nec faucibus erat. Donec tortor neque, convallis non felis vel, posuere ornare nunc. Fusce magna risus, interdum at pretium vel, finibus ut dolor. Vivamus congue ipsum non cursus tristique. Suspendisse in nulla accumsan, volutpat turpis eu, gravida sapien. Nam commodo velit vel tellus ultricies, ut consectetur neque molestie. Praesent tincidunt, libero ac elementum luctus, ex nisi volutpat leo, a hendrerit lacus leo eget tortor. Suspendisse viverra ante sit amet accumsan facilisis. Pellentesque velit nisl, luctus bibendum vulputate eget, dapibus at elit. Nam ac molestie turpis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Fusce cursus, magna non viverra rutrum, magna metus blandit tortor, sed elementum tellus lectus at velit. +Pellentesque habLorem ipsum dolor sit amet, consectetur adipiscing elit. Cras euismod massa sit amet tellus porta consectetur. Etiam aliquam pellentesque lorem id semper. Vestibulum ut rhoncus lacus, a blandit risus. Sed eget volutpat risus, eu molestie mi. Curabitur felis lacus, hendrerit id sollicitudin nec, sollicitudin in quam. Nunc pellentesque elit ac sapien tempor feugiat. Nunc ex urna, commodo in viverra a, tempus quis purus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; +Pellentesque pharetra mauris luctus felis cursus, id tempor sem viverra. Aenean fringilla, felis ut feugiat pretium, sapien lectus ornare enim, vel tempus mi tortor vitae lectus. Sed egestas mollis massa in dignissim. Sed placerat tellus id ligula molestie, id tincidunt sem rutrum. Aliquam erat volutpat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam est purus, maximus ut mi id, pharetra dictum lacus. Praesent ullamcorper libero metus, id ornare ex posuere ac. Ut tempor varius molestie. Sed a turpis lobortis, pretium leo ut, tempus turpis. Curabitur blandit ligula in mi pretium, sed varius libero tempus. Nunc pellentesque odio metus, vitae commodo neque eleifend ac. +Cras et est suscipit, suscipit dolor nec, blandit leo. Donec purus neque, rhoncus ac ullamcorper eget, placerat vel magna. Donec eu augue turpis. Fusce mattis nulla ante. Proin sit amet sem maximus, pharetra tortor et, sollicitudin eros. Curabitur elementum dolor ac metus vulputate ornare. Ut arcu libero, lobortis ac urna ut, ornare laoreet tortor. Vivamus sollicitudin suscipit efficitur. Ut nec nisi sed metus blandit bibendum. Nullam dictum accumsan sem, ac aliquam purus vestibulum sed. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut et ligula eget magna tempus interdum. Aliquam malesuada tempus imperdiet. Proin et elementum tellus, non aliquam magna. Sed id felis ut arcu aliquam aliquam eu nec nisi. +Donec dictum consequat quam nec malesuada. Nunc mattis iaculis vestibulum. Vestibulum erat lacus, mollis et tincidunt sit amet, tristique vitae massa. Phasellus ac vulputate dolor. Pellentesque ac auctor metus, nec faucibus erat. Donec tortor neque, convallis non felis vel, posuere ornare nunc. Fusce magna risus, interdum at pretium vel, finibus ut dolor. Vivamus congue ipsum non cursus tristique. Suspendisse in nulla accumsan, volutpat turpis eu, gravida sapien. Nam commodo velit vel tellus ultricies, ut consectetur neque molestie. Praesent tincidunt, libero ac elementum luctus, ex nisi volutpat leo, a hendrerit lacus leo eget tortor. Suspendisse viverra ante sit amet accumsan facilisis. Pellentesque velit nisl, luctus bibendum vulputate eget, dapibus at elit. Nam ac molestie turpis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Fusce cursus, magna non viverra rutrum, magna metus blandit tortor, sed elementum tellus lectus at velit. +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Morbi sollicitudin scelerisque sagittis. Cras mattis dictum sollicitudin. Donec tincidunt ullamcorper elit, non dignissim nulla ornare ac. Nulla at interdum nisl. Cras eget tincidunt neque. Etiam lobortis sem iaculis, accumsan augue vel, condimentum sem. Mauris porta congue nulla, id congue eros. Nullam nec arcu in ante elementum blandit sit amet ac nibh. Fusce eget risus tincidunt, viverra neque quis, pellentesque est. Sed et nisi nec massa consequat commodo pretium nec risus. Maecenas vestibulum diam ex, sit amet maximus lacus luctus scelerisque. Mauris eget ante sollicitudin, commodo purus eu, molestie tellus. Aliquam finibus eros nisi, eu cursus sapien pellentesque in. Cras eget justo tincidunt, congue lorem eu, dignissim metus.`; + +export default 'c'; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/foo.js b/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/foo.js new file mode 100644 index 00000000000..e06ff5ded86 --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/foo.js @@ -0,0 +1,4 @@ +import a from './a'; +import b from './b'; +import c from './c'; +export default a; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/index.js b/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/index.js new file mode 100644 index 00000000000..14be3f87ce4 --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/index.js @@ -0,0 +1,5 @@ +import('./foo'); +import('./bar'); +import('./buzz'); + +export default 1; diff --git a/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/local.html b/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/local.html new file mode 100644 index 00000000000..e1fd3f4ed29 --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/local.html @@ -0,0 +1,6 @@ + + + + Hello World + + diff --git a/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/package.json b/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/package.json new file mode 100644 index 00000000000..d94483f52b6 --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/package.json @@ -0,0 +1,6 @@ +{ + "@parcel/bundler-default": { + "minBundleSize": 200, + "maxParallelRequests":3 + } +} diff --git a/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/styles.css b/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/styles.css new file mode 100644 index 00000000000..c423315142e --- /dev/null +++ b/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/styles.css @@ -0,0 +1 @@ +p.groove {outline-style: groove;} diff --git a/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/yarn.lock b/packages/core/integration-tests/test/integration/shared-bundle-between-reused-bundle-removal/yarn.lock new file mode 100644 index 00000000000..e69de29bb2d From b90f7de372aa61ccfb41e7c53d7423af73f7ff3d Mon Sep 17 00:00:00 2001 From: Agnieszka Gawrys Date: Tue, 12 Jul 2022 18:32:20 -0400 Subject: [PATCH 05/10] add to source bundles for shared bundle --- packages/bundlers/experimental/src/ExperimentalBundler.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/bundlers/experimental/src/ExperimentalBundler.js b/packages/bundlers/experimental/src/ExperimentalBundler.js index 6f42b42a078..4a62509b30f 100644 --- a/packages/bundlers/experimental/src/ExperimentalBundler.js +++ b/packages/bundlers/experimental/src/ExperimentalBundler.js @@ -1078,6 +1078,9 @@ function createIdealGraph( for (let childId of bundleGraph.getNodeIdsConnectedFrom( bundleIdToRemove, )) { + let child = bundleGraph.getNode(childId); + invariant(child !== 'root' && child != null); + child.sourceBundles.add(sourceBundleId); bundleGraph.addEdge(sourceBundleId, childId); } // needs to add test case where shared bundle is removed from ONE bundlegroup but not from the whole graph! From 9cffae0f03dcc668d1565b00fa6ed235b1f07d64 Mon Sep 17 00:00:00 2001 From: Agnieszka Gawrys Date: Wed, 13 Jul 2022 12:55:13 -0400 Subject: [PATCH 06/10] lint --- packages/core/integration-tests/test/bundler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/integration-tests/test/bundler.js b/packages/core/integration-tests/test/bundler.js index 0d4af73b31f..ffcf853836f 100644 --- a/packages/core/integration-tests/test/bundler.js +++ b/packages/core/integration-tests/test/bundler.js @@ -152,7 +152,7 @@ describe('bundler', function () { ]); }); - it.only('should not remove shared bundle from graph if its parent (a reused bundle) is removed by parallel request limit', async function () { + it('should not remove shared bundle from graph if its parent (a reused bundle) is removed by parallel request limit', async function () { //The shared bundle should only be 'put back' for the bundlegroups which hit the parallel request limit // But if there are at least two other bundlegroups using this shared bundle that do not hit the max limit // the shared bundle should not be removed from the graph From c3180b2a385f3a98f64eeb2b2c4cd1eb8b59b59f Mon Sep 17 00:00:00 2001 From: Agnieszka Gawrys Date: Thu, 14 Jul 2022 16:42:13 -0400 Subject: [PATCH 07/10] disable test for default due to varied functionality --- .../core/integration-tests/test/bundler.js | 192 +++++++++--------- 1 file changed, 99 insertions(+), 93 deletions(-) diff --git a/packages/core/integration-tests/test/bundler.js b/packages/core/integration-tests/test/bundler.js index ffcf853836f..a96f9742a73 100644 --- a/packages/core/integration-tests/test/bundler.js +++ b/packages/core/integration-tests/test/bundler.js @@ -3,52 +3,54 @@ import assert from 'assert'; import {bundle, assertBundles, findAsset} from '@parcel/test-utils'; describe('bundler', function () { - it('should remove reused bundle (over shared bundles based on size) if the bundlegroup hit the parallel request limit', async function () { - let b = await bundle( - path.join( - __dirname, - 'integration/shared-bundle-reused-bundle-remove-reuse/index.js', - ), - { - mode: 'production', - defaultTargetOptions: { - shouldScopeHoist: false, + it.only('should remove reused bundle (over shared bundles based on size) if the bundlegroup hit the parallel request limit', async function () { + if (process.env.PARCEL_TEST_EXPERIMENTAL_BUNDLER) { + let b = await bundle( + path.join( + __dirname, + 'integration/shared-bundle-reused-bundle-remove-reuse/index.js', + ), + { + mode: 'production', + defaultTargetOptions: { + shouldScopeHoist: false, + }, }, - }, - ); + ); - assertBundles(b, [ - { - name: 'index.js', - assets: [ - 'index.js', - 'bundle-url.js', - 'cacheLoader.js', - 'css-loader.js', - 'esmodule-helpers.js', - 'js-loader.js', - 'bundle-manifest.js', - ], - }, - { - assets: ['bar.js', 'foo.js', 'a.js', 'b.js'], - }, - { - assets: ['buzz.js'], - }, - { - assets: ['c.js'], - }, - { - assets: ['a.js', 'b.js', 'foo.js'], - }, - { - assets: ['styles.css'], - }, - { - assets: ['local.html'], - }, - ]); + assertBundles(b, [ + { + name: 'index.js', + assets: [ + 'index.js', + 'bundle-url.js', + 'cacheLoader.js', + 'css-loader.js', + 'esmodule-helpers.js', + 'js-loader.js', + 'bundle-manifest.js', + ], + }, + { + assets: ['bar.js', 'foo.js', 'a.js', 'b.js'], + }, + { + assets: ['buzz.js'], + }, + { + assets: ['c.js'], + }, + { + assets: ['a.js', 'b.js', 'foo.js'], + }, + { + assets: ['styles.css'], + }, + { + assets: ['local.html'], + }, + ]); + } }); //This test case is the sdame as previous except we remove the shared bundle since it is smaller @@ -152,60 +154,64 @@ describe('bundler', function () { ]); }); - it('should not remove shared bundle from graph if its parent (a reused bundle) is removed by parallel request limit', async function () { + it.only('should not remove shared bundle from graph if its parent (a reused bundle) is removed by parallel request limit', async function () { //The shared bundle should only be 'put back' for the bundlegroups which hit the parallel request limit // But if there are at least two other bundlegroups using this shared bundle that do not hit the max limit // the shared bundle should not be removed from the graph - let b = await bundle( - path.join( - __dirname, - 'integration/shared-bundle-between-reused-bundle-removal/index.js', - ), - { - mode: 'production', - defaultTargetOptions: { - shouldScopeHoist: false, + if (process.env.PARCEL_TEST_EXPERIMENTAL_BUNDLER) { + let b = await bundle( + path.join( + __dirname, + 'integration/shared-bundle-between-reused-bundle-removal/index.js', + ), + { + mode: 'production', + defaultTargetOptions: { + shouldScopeHoist: false, + }, }, - }, - ); + ); - assertBundles(b, [ - { - name: 'index.js', - assets: [ - 'index.js', - 'bundle-url.js', - 'cacheLoader.js', - 'css-loader.js', - 'esmodule-helpers.js', - 'js-loader.js', - 'bundle-manifest.js', - ], - }, - { - assets: ['bar.js', 'foo.js', 'a.js', 'b.js'], // shared bundle merged back - }, - { - assets: ['buzz.js'], - }, - { - assets: ['c.js'], // shared bundle - }, - { - assets: ['foo.js', 'a.js', 'b.js'], - }, - { - assets: ['styles.css'], - }, - { - assets: ['local.html'], - }, - ]); + assertBundles(b, [ + { + name: 'index.js', + assets: [ + 'index.js', + 'bundle-url.js', + 'cacheLoader.js', + 'css-loader.js', + 'esmodule-helpers.js', + 'js-loader.js', + 'bundle-manifest.js', + ], + }, + { + assets: ['bar.js', 'foo.js', 'a.js', 'b.js'], // shared bundle merged back + }, + { + assets: ['buzz.js'], + }, + { + assets: ['c.js'], // shared bundle + }, + { + assets: ['foo.js', 'a.js', 'b.js'], + }, + { + assets: ['styles.css'], + }, + { + assets: ['local.html'], + }, + ]); - assert( - b - .getReferencedBundles(b.getBundlesWithAsset(findAsset(b, 'bar.js'))[0]) - .includes(b.getBundlesWithAsset(findAsset(b, 'c.js'))[0]), - ); + assert( + b + .getReferencedBundles( + b.getBundlesWithAsset(findAsset(b, 'bar.js'))[0], + ) + .includes(b.getBundlesWithAsset(findAsset(b, 'c.js'))[0]), + ); + } }); }); From 23b277dc8c3f7b8f02c207492158a78b96ff2be0 Mon Sep 17 00:00:00 2001 From: Agnieszka Gawrys Date: Thu, 14 Jul 2022 17:19:57 -0400 Subject: [PATCH 08/10] oops exclusive tests --- packages/core/integration-tests/test/bundler.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/integration-tests/test/bundler.js b/packages/core/integration-tests/test/bundler.js index a96f9742a73..df06f46ea08 100644 --- a/packages/core/integration-tests/test/bundler.js +++ b/packages/core/integration-tests/test/bundler.js @@ -3,7 +3,7 @@ import assert from 'assert'; import {bundle, assertBundles, findAsset} from '@parcel/test-utils'; describe('bundler', function () { - it.only('should remove reused bundle (over shared bundles based on size) if the bundlegroup hit the parallel request limit', async function () { + it('should remove reused bundle (over shared bundles based on size) if the bundlegroup hit the parallel request limit', async function () { if (process.env.PARCEL_TEST_EXPERIMENTAL_BUNDLER) { let b = await bundle( path.join( @@ -154,7 +154,7 @@ describe('bundler', function () { ]); }); - it.only('should not remove shared bundle from graph if its parent (a reused bundle) is removed by parallel request limit', async function () { + it('should not remove shared bundle from graph if its parent (a reused bundle) is removed by parallel request limit', async function () { //The shared bundle should only be 'put back' for the bundlegroups which hit the parallel request limit // But if there are at least two other bundlegroups using this shared bundle that do not hit the max limit // the shared bundle should not be removed from the graph From dedbdb618b424bb330e42e6ff4325015795b146a Mon Sep 17 00:00:00 2001 From: Gora Kong Date: Tue, 19 Jul 2022 17:10:36 -0700 Subject: [PATCH 09/10] break out of sourceBundle iteration after a bundle is removed --- packages/bundlers/experimental/src/ExperimentalBundler.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/bundlers/experimental/src/ExperimentalBundler.js b/packages/bundlers/experimental/src/ExperimentalBundler.js index 4a62509b30f..ea86bce083c 100644 --- a/packages/bundlers/experimental/src/ExperimentalBundler.js +++ b/packages/bundlers/experimental/src/ExperimentalBundler.js @@ -1097,6 +1097,8 @@ function createIdealGraph( ) { // If one bundle group removes a shared bundle, but the other *can* keep it, still remove because that shared bundle is pointless (only one source bundle) removeBundle(bundleGraph, bundleIdToRemove, assetReference); + // Stop iterating through bundleToRemove's sourceBundles as the bundle has been removed. + break; } else { bundleGraph.removeEdge(sourceBundleId, bundleIdToRemove); } From a1f80a03a6b3638b00241b1db1ff8db5f367217e Mon Sep 17 00:00:00 2001 From: Agnieszka Gawrys Date: Wed, 27 Jul 2022 14:11:00 -0400 Subject: [PATCH 10/10] fix comment --- packages/bundlers/experimental/src/ExperimentalBundler.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/bundlers/experimental/src/ExperimentalBundler.js b/packages/bundlers/experimental/src/ExperimentalBundler.js index ea86bce083c..da18a9018ad 100644 --- a/packages/bundlers/experimental/src/ExperimentalBundler.js +++ b/packages/bundlers/experimental/src/ExperimentalBundler.js @@ -915,17 +915,15 @@ function createIdealGraph( invariant(reusableBundle !== 'root' && reusableBundle != null); reusableBundle.sourceBundles.add(candidateSourceBundleId); } else { - // Asset is not a bundleRoot, but if its parent bundle can be - // reused as a subgraph of another bundle in its reachable, reuse it + // Asset is not a bundleRoot, but if its ancestor bundle (in the asset's reachable) can be + // reused as a subgraph of another bundleRoot in its reachable, reuse it for (let otherReuseCandidate of reachable) { if (candidateSourceBundleRoot === otherReuseCandidate) continue; let reusableCandidateReachable = getReachableBundleRoots( otherReuseCandidate, reachableRoots, ).filter(b => !ancestorAssets.get(b)?.has(otherReuseCandidate)); - if ( - reusableCandidateReachable.indexOf(candidateSourceBundleRoot) > -1 - ) { + if (reusableCandidateReachable.includes(candidateSourceBundleRoot)) { let reusableBundleId = nullthrows( bundles.get(otherReuseCandidate.id), );