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 new ESM loader runtime by moving to abs URLs #9172

Merged
merged 12 commits into from Aug 4, 2023
Merged

Conversation

mattcompiles
Copy link
Contributor

@mattcompiles mattcompiles commented Aug 1, 2023

↪️ Pull Request

This PR fixes the ESM loader runtime by making the bundle-manifest return absolute URLs. It also makes the following changes:

  • Faster manifest registration by using a Map and entries list rather than an object
  • Removes the ability to custom name runtime asset bundles
    • This is because it could break the absolute URL resolution

🚨 Test instructions

✔️ PR Todo

  • Added/updated unit tests for this change
  • Filled out test instructions (In case there aren't any unit tests)
  • Included links to related issues/PRs

packages/core/core/src/applyRuntimes.js Outdated Show resolved Hide resolved
packages/runtimes/js/src/JSRuntime.js Outdated Show resolved Hide resolved
packages/runtimes/js/src/helpers/bundle-manifest.js Outdated Show resolved Hide resolved
packages/core/core/src/applyRuntimes.js Outdated Show resolved Hide resolved
@@ -1,18 +1,17 @@
var mapping = {};
var mapping = new Map();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we ok to drop browsers that don't support Map? I think Parcel's output still worked in IE11 up until this point. Maybe it's ok, but wonder if it should be done in a major version?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe Map is supported in IE11. This support coverage looks good enough to me. But I can remove if you want.
https://caniuse.com/mdn-javascript_builtins_map

let baseUrl =
entryBundle.env.outputFormat === 'esmodule' &&
entryBundle.env.supports('import-meta-url')
? 'new __parcel__URL__("").toString()' // <-- this isn't ideal. We should use `import.meta.url` directly but it gets replaced currently
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@devongovett Thoughts on this? Seems reasonable that I should be able to use import.meta.url without it being replaced?

I could modify the transform to add a new special parcel symbol (e.g. __parcel_importMetaUrl__)? Or potentially add some asset meta data that prevents the stripping?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm yeah, I guess we could add a new __parcel thing, but does this work as is for now? if so I'm ok with leaving it as you have it as well.

@mattcompiles mattcompiles marked this pull request as ready for review August 2, 2023 03:51
@marcins
Copy link
Contributor

marcins commented Aug 3, 2023

Benchmarks are failing in the size comparison code (https://github.com/parcel-bundler/parcel-benchmark-action/blob/master/src/utils/compare-benchmarks.ts#L37-L65) - my guess is this is because it expects all the bundles produced in the baseline to also be present in the target, and you've renamed some of the runtime bundles.

Copy link
Member

@devongovett devongovett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks ok. couple questions but I wouldn't consider them blocking

mapping.set(manifest[i], {
baseUrl: baseUrl,
path: manifest[i + 1],
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could do the new URL thing here instead of storing both and doing it every time we resolve?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I originally did this, but I pivoted as creating the URLs is not free CPU wise. We have a huge manifest and creating 100's of URLs in startup isn't ideal. I believe it's better perf wise to create on demand. We could cache in future if need be though but I just kept it simple.

if (resolved == null) {
throw new Error('Could not resolve bundle with id ' + id);
}
return resolved;
return new URL(resolved.path, resolved.baseUrl).toString();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one definitely won't work in IE. Probably ok at this point? I guess we can't simply concatenate the strings? path could probably start with ../ or something...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah not ideal. We could just recommend a polyfill for URL if anyone has issues I guess.

@mattcompiles mattcompiles merged commit 88e6db4 into v2 Aug 4, 2023
15 of 16 checks passed
@mattcompiles mattcompiles deleted the esm-runtime-fix branch August 4, 2023 00:43
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

3 participants