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

Fix cannot find module error with runtimes in multiple bundles #9646

Open
wants to merge 2 commits into
base: v2
Choose a base branch
from

Conversation

devongovett
Copy link
Member

Closes #9196

This fixes a cannot find module error that occurs when you have an HTML page with two script tags, each with an async import. It occurs because runtimes are processed in reverse order, so the bundle manifest gets put in the second script tag rather than the first, even though the first also has a dependency on it.

This behavior was introduced in #8837 and subsequently updated in #8981. I believe the intent was to place parallel runtime bundles before the bundles that used them, but it inadvertently also changed the order of other runtimes as well. The fix is to handle parallel runtimes separately, by inserting them at the beginning of the list of connections instead of the end, while treating other runtimes normally.

Added test and existing tests pass, but would be good to verify in applications.

@mattcompiles
Copy link
Contributor

Looks good @devongovett. I'll test this and get back to you.

@mattcompiles
Copy link
Contributor

Hey @devongovett
I tested this locally and I'm getting a bunch of Could not resolve bundle with id errors. When I search the dist directory though I can't see any bundles that actually define the bundle ID though, only references. 🤔

@devongovett
Copy link
Member Author

Oh no! What are we missing here? I thought the logic made sense...

@mattcompiles
Copy link
Contributor

@devongovett Comparing the outputs I can see that there's runtime bundles being missed in the manifests which causes the error. I'm 95% sure this is because you removed the reverse topological processing of the bundles.

i.e.

  // As manifest bundles may be added during runtimes we process them in reverse topological
  // sort order. This allows bundles to be added to their bundle groups before they are referenced
  // by other bundle groups by loader runtimes
  let bundles = [];
  bundleGraph.traverseBundles({
    exit(bundle) {
      bundles.push(bundle);
    },
  });

@devongovett
Copy link
Member Author

@mattcompiles but the reverse order was what caused the other issue that this PR is supposed to solve... so not sure what we should do here. Maybe it somehow needs to be done in two passes: first generate all the runtimes (including creating new bundles), and then generate the manifests once all bundles are known?

Are those missing runtime bundles generated by a custom plugin or the JS runtime? If the JS runtime, I think the only use of parallel runtimes is for the manifest itself. Can manifest bundles point to other manifest bundles? Are those the ones that are missing?

I guess we are missing a test here because the tests that were added in the original PRs for this feature seem to be passing. So that's why I'm wondering if maybe it's a custom plugin in Jira?

@mattcompiles
Copy link
Contributor

mattcompiles commented Apr 18, 2024

@devongovett

Are those missing runtime bundles generated by a custom plugin or the JS runtime?

There's no Jira specific code here. The code that decides whether a new bundle should be inserted is here: https://github.com/parcel-bundler/parcel/blob/331bed8a62b7073f4748ca8c8d150068f1fdde9a/packages/runtimes/js/src/JSRuntime.js#L723C6-L723C7

Can manifest bundles point to other manifest bundles? Are those the ones that are missing?

Yes, this is the problem that's occurring. If you don't run reverse order, you end up inserting bundles in children, but the parent manifests have already been written.

I guess we are missing a test here because the tests that were added in the original PRs for this feature seem to be passing.

There does seem to be a test missing here, I guess that's my bad. I'll see if I can replicate the issue in a test.

@mattcompiles
Copy link
Contributor

I've tried creating a test to replicate the scenario I'm seeing locally but no luck so far. I do know that it's related to manual shared bundles that get assigned a runtime bundle though. I'll keep thinking about we can replicate it in a test. I'd also be happy to pair on it sometime if it would help. Don't want to block your fixes going out.

@devongovett
Copy link
Member Author

Interesting. Maybe some kind of circular bundle reference? It sorta makes sense that you need all the bundles that will be referenced to have been created before you can correctly build the manifest. But on the other hand, bundles within the same bundle group get executed in order, so shared runtimes need to be placed in earlier bundles. Kind of a catch-22. That's why I mentioned needing two passes - one to create the bundles and a second to actually generate the manifests. But that would be a pretty big change to the API for runtimes...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants