babel / babel/babel

[Feature Request] Please use async-to-promise rather than async-to-generator

Open
#8,121 4 comments 35 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
44k
Forks
6k
Avg merge
5d 15h
Merged PRs (30d)
23

Description

## Feature Request

**Is your feature request related to a problem? Please describe.**

In order to use async functions with present-env in IE11 the _entire_ babel-pollyfill plugin needs to be downloaded by users just so that `regeneratorRuntime` is not undefined (a function that only Babel uses by the way).

This gives an idea of the sort of impact that the download alone has:
https://bundlephobia.com/result?p=babel-polyfill@6.26.0

On top of that, every single time you include an async function it massively blows out the code size.

For example take this basic bit of js:

```js
var that = async function(){
var thing = await fetch('https://dog.ceo/api/breeds/image/random').then(resp => resp.json());
console.log(thing);
return thing;
}
var result = that();
```

It will get blown out into this:

````js

var that = function that() {
var thing;
return regeneratorRuntime.async(function that$(context$2$0) {
while (1) switch (context$2$0.prev = context$2$0.next) {
case 0:
context$2$0.next = 2;
return regeneratorRuntime.awrap(fetch('https://dog.ceo/api/breeds/image/random').then(function (resp) {
return resp.json();
}));

case 2:
thing = context$2$0.sent;

console.log(thing);
return context$2$0.abrupt('return', thing);

case 5:
case 'end':
return context$2$0.stop();
}
}, null, this);
};
var result = that();

````

**Describe the solution you'd like**

I really like how [babel-plugin-async-to-promises](https://www.npmjs.com/package/babel-plugin-async-to-promises) handles the translation of async functions. It seems like the far more logical approach. The output is more human readable and also creates less code bloat.

````js
var that = function that() {
var thing;
return Promise.resolve().then(function () {
return fetch('https://dog.ceo/api/breeds/image/random').then(function (resp) {
return resp.json();
});
}).then(function (_resp) {
thing = _resp;

console.log(thing);
return thing;
});
};
var result = that();
````

The other major advantage it has over the generator method is that the only thing it needs to work is a Promise polyfill. Promises are things that developers are able to take advantage of in their regular source code. This makes a Promise polyfill a more worth while investment than all the code necessary to make `regeneratorRuntime` work which developers don't use in their source code. Promise is also a native browser API so only the browsers that don't understand it have to download it. Smart devs can prevent modern browsers from downloading the polyfill code. `regeneratorRuntime` is not standard code so all browsers have to download the entire babel-pollyfill library no matter what.

The plugin doesn't seem to overide the preset-env functionality so I can't use it if env is the preset. It was built to run on the es2015 preset. I'm not sure if straight swapping out the async-to-generator code with async-to-promise will work.

There are some concerns with swapping to the already built async-to-promise plugin. For one, it hasn't really been worked on in a while (last commit was 2 years ago >_<). It also says it " is usable, but it's also not complete yet" which doesn't give much confidence.

**Describe alternatives you've considered**

Straight swapping out async-to-generator with async-to-promise might not be the best way forward. I'm creating this issue as a way of pointing out the flaws in the current async translation implementation in babel-preset-env. I'm hoping that async-to-promise functionality can be implemented into the core env preset in some way.

**Teachability, Documentation, Adoption, Migration Strategy**

- Replace async-to-generator with async-to-promise
- Remove the `regeneratorRuntime` code from babel-polyfill (unless this is needed for generator functions).
- advise people to install a promise polyfill in documentation or install babel-polyfill.
- Release the changes in a new major version bump

Contributor guide

Open the contributing guide

Research direction

Start by reviewing babel-preset-env's async-to-generator handling and the babel-polyfill regeneratorRuntime behavior described in the issue. Compare the requested async-to-promise translation and its Promise-polyfill assumptions, then determine whether the preset, polyfill, and documentation changes are complete; verify generated output for the supplied async example.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.