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

Support asynchronous configuration #9888

Closed
guybedford opened this issue Apr 22, 2019 · 13 comments
Closed

Support asynchronous configuration #9888

guybedford opened this issue Apr 22, 2019 · 13 comments
Labels
i: enhancement outdated A closed issue/PR that is archived due to age. Recommended to make a new issue

Comments

@guybedford
Copy link
Contributor

I couldn't find an existing tracking issue for this feature, please mark as a duplicate if I've missed anything.

This is something that would be required for jspm support in Babel CLI, where we'd want to use dynamic import() to reference plugins directly, and so would need some kind of promise support in the configuration.

Currently an asynchronous configuration gives the following error:

Error: You appear to be using an async configuration, which your current version of Babel does not support. We may add support for this in the future, but if you're on the most recent version of @babel/core and still seeing this error, then you'll need to synchronously return your config.

And an asynchronous plugin gives the following error:

You appear to be using an async plugin, which your current version of Babel
does not support.If you're using a published plugin, you may need to upgrade your @babel/core version.

Either or both of these features would be really great to support.

The async plugin case effectively provides parity with top-level await workflows in future too. Happy to discuss further as well.

@babel-bot
Copy link
Collaborator

Hey @guybedford! We really appreciate you taking the time to report an issue. The collaborators
on this project attempt to help as many people as possible, but we're a limited number of volunteers,
so it's possible this won't be addressed swiftly.

If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack
community
that typically always has someone willing to help. You can sign-up here
for an invite.

@nicolo-ribaudo
Copy link
Member

While developing Babel 7 beta, we added that errors to be able to introduce async config/plugins during the Babel 7 lifetime without breaking changes.

The biggest problem is that currently Babel can be called synchronously (var out = babel.transform(code, options)), and there is no way to make it work with async config/plugins.

@guybedford
Copy link
Contributor Author

Thanks for clarifying. Ok so how can we do this safely? Just throw when running under the sync transform only?

@nicolo-ribaudo
Copy link
Member

Just throw when running under the sync transform only?

Either that, or https://github.com/abbr/deasync.

I have done some research to understand how hard would be for the ecosystem to support async Babel configurations:

  1. babel-loader will support it without any change, it already uses Babel's async api.
  2. rollup-plugin-babel can be easily updated: it call's Babel sync transform inside an async function
  3. ESLint doesn't support async parsers: this is a problem for babel-eslint

@loganfsmyth
Copy link
Member

When I added the error my intention was to eventually

  1. Throw an exception if a plugin/config returns a promise in a context where Babel is used synchronously
  2. Expose an API on the first function parameter so that plugins could check which whether promises would be allowed, and change their behavior depending on that. That way a plugin could be async ideally and fall back to a sync implementation if it wanted or something.

That way if a plugin really wanted to use deasync or something, it could, but it wouldn't be something we'd do in our own plugins, or necessarily recommend, since that module really is ugly.

It'd also be interesting to continue working to make other implementations async, or at least optionally async. I had thought for instance that @babel/register could expose a mode that would precompile all of the modules in a set of files, before executing the application entrypoint, for instance, so require could be sync, but compilation could be async.

@guybedford
Copy link
Contributor Author

There seem to be quite a lot of ways to come at this problem.

Note also that an alternative way to support the use case mentioned above for jspm would be if Babel would support top-level await in the babel.config.js file.

If I created a tracking issue specifically for top-level await in babel.config.js would that be something that would be considered for a PR?

@nicolo-ribaudo
Copy link
Member

nicolo-ribaudo commented May 22, 2019

Since we aren't transpiling babel.config.js, supporting async configurations is way easier.

Also, I think that when plugins will be written using native node esm we will be forced to resolve them asynchronously, since we load them dynamically.

@guybedford
Copy link
Contributor Author

@nicolo-ribaudo do you mean this is because it is loaded via require("path/to/babel.config.js")?

I think that this can be made to support top-level await with a pattern something like (exact details may be slightly off since I'm writing this in a github comment):

function asyncRequire (name) {
  const Module = require('module').Module;
  const m = new Module(name);
  m.paths = Module._nodeModulePaths(path.resolve(name));
  const promise = eval(`(async function (exports, require, module, __filename, __dirname) {
${fs.readFileSync(name).toString()};
})(m.exports, m.require, m, __filename, __dirname)`;
  return promise;
}

@guybedford
Copy link
Contributor Author

Or preferably in the above via vm.runInThisContext.

@javadbat
Copy link

javadbat commented Aug 21, 2019

any progress? we really need this feature

@loganfsmyth
Copy link
Member

@javadbat Not presently.

Would you be able to elaborate on the usecase you are hoping for? Even if we implement this, there will be cases where it is not supported, like with @babel/node and @babel/register.

@javadbat
Copy link

I just want to be able to transpile our react app on the fly in browser for each page with systemjs 2 for Dev environment

@nicolo-ribaudo
Copy link
Member

nicolo-ribaudo commented Jan 31, 2021

Fixed by #12266, it will be released in 7.13.0

@github-actions github-actions bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label May 3, 2021
@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 3, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
i: enhancement outdated A closed issue/PR that is archived due to age. Recommended to make a new issue
Projects
None yet
Development

No branches or pull requests

5 participants