Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make getReferencedBundle faster #7416

Merged
merged 4 commits into from Dec 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 7 additions & 12 deletions packages/core/core/src/BundleGraph.js
Expand Up @@ -417,6 +417,7 @@ export default class BundleGraph {
};
}

// eslint-disable-next-line no-unused-vars
getReferencedBundle(dependency: Dependency, fromBundle: Bundle): ?Bundle {
let dependencyNodeId = this._graph.getNodeIdByContentKey(dependency.id);

Expand All @@ -436,24 +437,18 @@ export default class BundleGraph {
});
}

// Otherwise, it may be a reference to another asset in the same bundle group.
// Resolve the dependency to an asset, and look for it in one of the referenced bundles.
let referencedBundles = this.getReferencedBundles(fromBundle, {
includeInline: true,
});
let referenced = this._graph
// Otherwise, find an attached bundle via a reference edge (e.g. from createAssetReference).
let bundleNode = this._graph
.getNodeIdsConnectedFrom(
dependencyNodeId,
bundleGraphEdgeTypes.references,
)
.map(id => nullthrows(this._graph.getNode(id)))
.find(node => node.type === 'asset');
.find(node => node.type === 'bundle');

if (referenced != null) {
invariant(referenced.type === 'asset');
return referencedBundles.find(b =>
this.bundleHasAsset(b, referenced.value),
);
if (bundleNode) {
invariant(bundleNode.type === 'bundle');
return bundleNode.value;
}
}

Expand Down
23 changes: 17 additions & 6 deletions packages/core/integration-tests/test/cache.js
Expand Up @@ -2,11 +2,13 @@
import type {InitialParcelOptions, BuildSuccessEvent} from '@parcel/types';
import assert from 'assert';
import invariant from 'assert';
import nullthrows from 'nullthrows';
import path from 'path';
import {
assertBundles,
bundler,
run,
runBundle as runSingleBundle,
overlayFS,
outputFS,
inputFS,
Expand Down Expand Up @@ -149,9 +151,9 @@ describe('cache', function () {
});

it('should support adding a dependency which changes the referenced bundles of a parent bundle', async function () {
async function exec(bundleGraph) {
async function exec(bundleGraph, bundle) {
let calls = [];
await run(bundleGraph, {
await runSingleBundle(bundleGraph, nullthrows(bundle), {
call(v) {
calls.push(v);
},
Expand All @@ -161,19 +163,28 @@ describe('cache', function () {

let b = await testCache(
{
entries: ['index.html'],
entries: ['a.html', 'b.html'],
mode: 'production',
update: async b => {
assert.deepEqual(await exec(b.bundleGraph), ['a', 'b']);
let html = b.bundleGraph.getBundles().filter(b => b.type === 'html');
assert.deepEqual(await exec(b.bundleGraph, html[0]), ['a']);
assert.deepEqual(await exec(b.bundleGraph, html[1]), ['b']);
await overlayFS.writeFile(
path.join(inputDir, 'a.js'),
'import "./b.js"; call("a");',
'import "./c.js"; call("a");',
);
await overlayFS.writeFile(
path.join(inputDir, 'b.js'),
'import "./c.js"; call("b");',
);
},
},
'cache-add-dep-referenced',
);

assert.deepEqual(await exec(b.bundleGraph), ['b', 'a']);
let html = b.bundleGraph.getBundles().filter(b => b.type === 'html');
assert.deepEqual(await exec(b.bundleGraph, html[0]), ['c', 'a']);
assert.deepEqual(await exec(b.bundleGraph, html[1]), ['c', 'b']);
});

it('should error when deleting a file', async function () {
Expand Down
@@ -1,3 +1,2 @@
<!DOCTYPE html>
<script type="module" src="./a.js"></script>
<script type="module" src="./b.js"></script>
@@ -0,0 +1,2 @@
<!DOCTYPE html>
<script type="module" src="./b.js"></script>
@@ -0,0 +1 @@
call("c");
@@ -0,0 +1,5 @@
{
"@parcel/bundler-default": {
"minBundleSize": 0
}
}