@shim-works/babel-plugin-transform-async-to-promises
v0.8.19
Published
Transform async/await to promise chains
Maintainers
Readme
@shim-works/babel-plugin-transform-async-to-promises
Babel plugin to transform async functions containing await expressions to the equivalent chain of Promise calls with use of minimal helper functions.
Fork notice
This is a fork of rpetrich/babel-plugin-transform-async-to-promises, whose last release was
0.8.18in December 2021. All credit for the plugin belongs to Ryan Petrich; it remains MIT licensed under his copyright.Versions track upstream:
0.8.19is upstream0.8.18plus the changes below.Supports Babel 6 and Babel 7, matching upstream. Babel 8 is not supported.
Bugs fixed
Both reproduce against upstream
0.8.18and are covered by the test suite.
- #84 —
_async is not defined. WithtopLevelAwait: "return"and@babel/plugin-transform-modules-systemjs, the output called_async(...)without ever emitting the helper, so the module threwReferenceErrorat runtime.Could not find newly created binding for _temp!— thrown when compiling anasyncfunction where afor...ofwraps atry/catchcontainingawait, withhoist: trueand@babel/preset-envdownlevellingfor...offor an older target. Babel'sScope#pushdescends into the loop body and registers the binding on a descendant scope, whilegetBindingonly walks up.Hardening
No failing test behind these — they were verified not to change output across 792 transform pairs on Babel 6 and Babel 7.
- Keeps the parsed helper cache per plugin instance rather than per module, so two Babel versions sharing a process cannot reuse each other's helper ASTs.
- Skips await expressions in subtrees an earlier rewrite has already detached. This only misbehaves under Babel 8, which is unsupported here, so it is forward-looking.
- Adds the regression test from upstream PR #94. The bug it covers (#90) was already fixed in
0.8.18; the test pins it.
Install:
npm install --save-dev @shim-works/babel-plugin-transform-async-to-promises// babel.config.json
{
"plugins": ["@shim-works/babel-plugin-transform-async-to-promises"]
}Input:
async function fetchAsObjectURL(url) {
const response = await fetch(url);
const blob = await response.blob();
return URL.createObjectURL(blob);
}Output:
const fetchAsObjectURL = _async(function(url) {
return _await(fetch(url), function(response) {
return _await(response.blob(), URL.createObjectURL);
});
});Output with hoist enabled:
function _response$blob(response) {
return _await(response.blob(), URL.createObjectURL);
}
const fetchAsObjectURL = _async(function(url) {
return _await(fetch(url), _response$blob);
});Output with inlineHelpers enabled:
const fetchAsObjectURL = function(url) {
try {
return Promise.resolve(fetch(url)).then(function(response) {
return Promise.resolve(response.blob()).then(URL.createObjectURL);
});
} catch(e) {
return Promise.reject(e);
}
}Output with externalHelpers enabled:
In the normal case, helpers are added to the top of the file for the _async and _await functions (as well as others). This can cause bloat in a codebase due to duplication of helper code in every file. To avoid this, enable externalHelpers and those will be imported instead:
import { _async } from "@shim-works/babel-plugin-transform-async-to-promises/helpers";
import { _await } from "@shim-works/babel-plugin-transform-async-to-promises/helpers";
const fetchAsObjectURL = _async(function(url) {
return _await(fetch(url), function(response) {
return _await(response.blob(), URL.createObjectURL);
});
});
export default fetchAsObjectURL;JavaScript Language Features
Full Support
async/awaitfor/while/doloops (including loops that would exhaust stack if dispatched recursively)switchstatements (including fallthrough anddefaultcases)- conditional expressions
- logical expressions
try/catchbreak/continuestatements (on both loops and labeled statements)throwexpressions- Function hoisting
- Variable hoisting
- Arrow functions
- Methods
argumentsthis- Proper member dereference order of operations
- Standards-compliant event loop scheduling
Partial Support
Function.length:asyncfunctions will often return a length of 0 (when the_asyncwrapper is used)- Top level await support is experimental with compatible module bundler. Set
topLevelAwaitoption toreturnwhen using SystemJS.
No support
eval: impossible to support without deep hooks into the runtime- Async generator functions: not implemented or planned
Function.name: rewrite pass removes function name instrumentationnew AsyncFunction(...): impossible to support without shipping babel and the plugin in the output
