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
Refactor handling of import.meta.url and add option to configure behaviour #2785
Conversation
df9ae4e
to
e3ae259
Compare
I've posted rollup-test which demonstrates how I could use the
Obviously this is a silly example but the whole point is that if Unfortunately an My basic idea: const bundleURL = {
amd: 'new URL(module.uri, document.baseURI).href',
esm: 'import.meta.url',
// all other formats as you declared above..
};
function getImportMetaReplacementURL(output, chunkId, moduleId) {
if (output.relativeMeta) {
const relativeURL = JSON.stringify(output.relativeMeta(chunkId, moduleId));
// simplified example omits the `require('url')` needed for some formats to get URL
return `new URL(${relativeURL}, ${bundleURL[output.format]}).href`;
}
if (output.importMetaUrl) {
return output.importMetaURL(chunkId, moduleId);
}
return bundeURL[output.format];
} In theory Sorry this response got so long, thanks for working on this. |
I think this a good solution, and we can iterate over different solutions for setting the final bundled import.meta.url. |
81a8fc1
to
ef4109e
Compare
Following communication with @guybedford, I changed the implementation to use a plugin hook instead of an output option. This has the advantage that this can now easily be packed into a plugin that e.g. also does asset handling (otherwise there might be conflicts between plugins and options). The hook is synchronous and all usages of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Amazing, this looks really powerful now!
@justinfagnani I'm sure you'll be very pleased to see this finally.
@guybedford thanks for the tag. What changed? We haven't been able to use Rollup's The big things we need are
Glad there's work here. We can try this out soon I think. Along with #2772 we might be able to replace Polymer Bundler with a Rollup plugin. |
Changing the default could certainly be possible in a new major version but there are some concerns I have about it. Especially the fact that there might be no "naturally correct" URL to resolve to. Example: There are two entry points in I certainly see that we are taking the easy way out here by saying: Not transpiling About the object form: What is your use-case here? I was thinking about extending the hook to handle arbitrary |
Please also note that |
There very much is though: load the project without bundling. Whatever each individual module's
The URLs should be the relative patch between the chunk and the bundlined module, with a base of the chunk, which should be the original URL of the module. So if the chunk is output to
No difference. Their
I think the only assumption is that the program should work the same as before bundling. Prior to bundling the semantics are very clear.
In Polymer we allow passing the meta object into a base class that does path manipulation on CSS to correctly load relative resources. We accept the meta object just as convenience, and in case in the future there were other meta properties that the base class might need. It looks like this: class A extends PolymerElement {
static get importMeta() { return import.meta; }
} The base class can then access That's why we rewrite |
Another way to derive the correct rewrite is that in a module |
I see. So what you want is that if you serve your complete project folder including all sources and compiled output files, the behaviour should be the same. This is definitely useful but I am not sure that serving all their sources is everyones use-case. Another way of using it could be to copy files next to the processed chunks which would work well with the current state of things. For the time being, I would stick with this PR as it is a non-breaking change, but we can consider changing it for the next major. In any case, having a hook to configure it seems to be very helpful. About replacing As "optimal" defaults are really very much subjective, how about generalizing the plugin hook in the following way: resolveImportMeta: (prop: string | null, {moduleId: string, chunkId: string}) => string | null
|
Another thing to consider with your proposal is how to handle files "outside" the base folder. For instance when bundling to |
I think this is not an issue. Object spread is stage 4,
I appreciate this. Any change to the current default handling of |
Good point! |
I changed the hook to handle ALL |
039afa1
to
057ecda
Compare
This PR contains:
Are tests included?
Breaking Changes?
List any relevant issue numbers:
Resolves #2748
Description
This will refactor the current default handling of
import.meta.url
in several important ways:cjs
andumd
assume the code runs in a browser environment whereURL
anddocument
are availablecjs
andumd
, presence of a browser environment is detected by checking fordocument
(after which presence ofURL
is assumed)new URL('my/bundle.js', document.baseURI).href
, but this is only the last option if e.g.document.currentScript.src
is not available.Generated code:
Also by using the new
resolveImportMetaUrl
plugin hook, it is now possible to customize this behaviour to e.g. always resolve using the original module paths. Example (I also put this into the docs):