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
Allow preset-env to toggle module handling based on flags from the caller (like babel-loader) #8485
Conversation
Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/8854/ |
Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/8829/ |
@Andarist Any thoughts on this, since it'll probably fit nicely into your work on the Rollup plugin too. |
// When the `exclude` callback returns a truthy value, Babel not use the | ||
// 'item' plugin here. | ||
overrides.push({ | ||
exclude: (filename, { caller }) => caller && caller.supportsStaticESM, |
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.
Since the caller
isn't file-specific but it is more similar to env
, can we pass it using the api
object instead using the exclude
option (which is usally used to exclude plugins based on the file path)?
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.
That's a great question. Let me revisit that. This approach was from an old branch I had, so I hadn't acutally revisited that. My concern would be caching of plugin instances. The issue with caching is that the API would need to be
const supportsStaticESM = api.caller(caller => !!(caller && caller.supportsStaticESM));
because your build might be used both with and without static ESM support, and Babel needs to know whether or not it should re-evaluate the plugin function, since it does its best to only evaluate the plugin/preset functions a single time unless told otherwise.
I'm actually fine if we want to expose the api
approach, but I'd still probably be tempted to leave this exposed in test/include/exclude
too.
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.
Caller is an object that can only contain null
, undefined
, booleans, strings, and numbers: it can be JSON.stringify
ed and stored to invalidate the cache when needed.
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.
That's true, I'm personally not a huge fan of that because we could always want to expand that in the future, and having to re-stringify the object all the time just seems undesirable. At the end of the day I don't feel that strongly about it I guess. One other downside being that the plugin cache would get invalidated if any caller flag changed, even if it was something other than supportsStaticESM
.
export function buildPresetChain( | ||
arg: PresetInstance, | ||
context: *, | ||
): ConfigChain | null { |
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.
This function never returns null.
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.
Oh good catch.
Does Babel use the same config validation for config files and options directly passed to |
Already done! |
5e28652
to
a68f3e8
Compare
moduleTransformations[modules] && | ||
// TODO: Remove the 'api.caller' check eventually. Just here to prevent | ||
// unnecessary breakage in the short term for users on older betas/RCs. | ||
(modules !== "auto" || !api.caller || !api.caller(supportsStaticESM)) |
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.
@nicolo-ribaudo Thoughts? Ended up exposing both and using the api.caller
approach I mentioned.
a68f3e8
to
d60c5e1
Compare
}); | ||
|
||
it("`false` option returns commonjs", () => { | ||
it("`false` option returns false", () => { |
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.
🤦♂️
This is really great! Something we should document for our integrations to also take advantage of. |
🚀 super! Sorry I've missed this PR before, but this is super awesome - preventing the users misconfiguring their tool in clean way, gonna land this in rollup-plugin-babel once it gets released |
This resolves a frustrating error I encountered where I was receiving: ReferenceError: Unknown option: .caller ...when trying to use `@babel/register`. This mysteriously went away when I upgraded to `rc.2`, which was inspired after I honed in on related work to the `caller` option in babel/babel#8485 after debugging Babel's `loadOptions` (in `7.0.0-rc.1`) with the Node.js debugger.
` - 'false' to indicate no module processing\n` + | ||
` - a specific module type: 'commonjs', 'amd', 'umd', 'systemjs'` + | ||
` - 'auto' (default) which will automatically select 'false' if the current\n` + | ||
` process is known to support ES module syntax, or "commonjs" otherwise\n`, |
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.
Hi, I have a ❓ about "if the current process is known to support ES module syntax". I'm not sure what that means. Can someone please clarify? Thank you!
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.
For example, if you are calling Babel using babel-loader
, modules
will be set to false because webpack supports ES modules
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.
Thanks @nicolo-ribaudo, I'll link to your reply from babel/babel-loader#521 😃
What this PR essentially means is that utilities calling Babel can:
For instance,
babel-loader
would be able to do:and
preset-env
can automatically change its behavior frommodules: "commonjs"
tomodules: false
.