fast-async's People
Forkers
fend25 nightwolfz chrisantaki amilajack ephemer zsea pebsconsulting zoecarver strate asleepysamurai texodus gordlea taoyuan forky-mcforkfacefast-async's Issues
Clobbers single line function definition export
Will rewrite an exported function into a non-exported given for example:
export async function foo() {}
This then requires a manual export later in the file.
Strange "unexpected token" errors
Sorry for being vague, but I think there is something funny going on with this plugin.
When I use these plugins,
'syntax-async-functions',
'transform-async-to-generator',
'transform-regenerator',
["transform-runtime", {
"polyfill": true,
"regenerator": true,
}],
My project compiles fine, but when I try with:
'syntax-async-functions',
['fast-async',{
compiler: {
promises: true,
generators: false
}
}],
["transform-runtime", {
"polyfill": true,
"regenerator": false,
}],
I get a bunch of errors like this:
ERROR in ./assets/scripts/lib/DynamicSelect.js
Module parse failed: /home/mpenner/Projects/webenginex/node_modules/babel-loader/index.js?{"presets":[],"plugins":["syntax-flow","syntax-trailing-function-commas","check-es2015-constants","transform-flow-strip-types","transform-es3-member-expression-literals","transform-es3-property-literals","transform-es5-property-mutators",["transform-es2015-modules-commonjs",{"loose":true}],"transform-class-constructor-call","transform-class-properties","transform-decorators","transform-export-extensions","transform-object-rest-spread","transform-exponentiation-operator","transform-es2015-arrow-functions","transform-es2015-block-scoped-functions","transform-es2015-block-scoping","transform-es2015-classes","transform-es2015-computed-properties","transform-es2015-destructuring","transform-es2015-for-of","transform-es2015-function-name","transform-es2015-literals","transform-es2015-object-super","transform-es2015-parameters","transform-es2015-shorthand-properties","transform-es2015-spread","transform-es2015-sticky-regex","transform-es2015-template-literals","transform-es2015-typeof-symbol","transform-es2015-unicode-regex","syntax-async-functions",["fast-async",{"compiler":{"promises":true,"generators":false}}],["transform-runtime",{"polyfill":true,"regenerator":false}]],"compact":false}!/home/mpenner/Projects/webenginex/assets/scripts/lib/DynamicSelect.js Line 71: Unexpected token
You may need an appropriate loader to handle this file type.
| var $ = require('jquery');
|
| export {};
| export {};
|
@ ./assets/main.js 149:35-73
I'm not even sure what the syntax error is. Those empty export {};
s weren't in my code, but I don't think they're a syntax error. And async
isn't even used in this file. So I really have no idea what's going on, but I'm pretty sure it has something to do with fast-async
.
Merge this project into the official async plugin for Babel?
Right now there are a few ways to use (non-native) async in Babel:
- Babel + regenerator: https://github.com/facebook/regenerator
- Babel + kneden: https://github.com/babel/kneden
- Babel + async-to-gen: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-async-to-generator
We also had a module called async-to-module-method
but it seemed weird to make it separate so I just merged that as an option in the other async plugin.
I'd like to propose we just merge everything into 1 plugin?
So in v7 it would be called @babel/plugin-async-functions
and it would have an option to compile using generators (async-to-gen) and promises (using a port of this plugin + kneden).
I'd like this because regenerator has to have a runtime, it's large, and still under the BSD+Patents by FB (waiting for them to change it). If in the meantime we can get this working I'm cool with just switching it out by default and other people can opt-in to using regenerator if they want but it would be outside of our repo.
Would that be desirable? Basically for this new plugin I would want everything in fast-async
that is related to compiling async to promises but nothing else (so don't need the logic for generators, or any non-spec behavior that is in nodent). Let me know if that would be cool, or if we can get someone else in the community to do this if you are busy
So the new version wouldn't need all of https://github.com/MatAtBread/nodent or https://github.com/MatAtBread/nodent-runtime or the options
Warning: a promise was created in a handler at eval at processIncludes
Not sure if this is relevant but when I changed my config to fast-async
I started getting such warnings from bluebird
:
(node:22057) Warning: a promise was created in a handler at eval at processIncludes (/code/project/node_modules/nodent-runtime/runtime.js:1:0), <anonymous>:3:4642 but was not returned from it, see http://goo.gl/rRqMUw
I'd rather not disable the warning itself as it may be useful on other occasions.
Do you think it's a problem in fast-async? or maybe in bluebird? or maybe the change has just uncovered my own bug...
Strict mode transformation bug on IOS
Code:
class exampleClass {
async fun1(){}
async fun2() {
const channel = await this.fun1();
try {return await this.fun1();} catch(e) {
return false;
}
}
}
export default EpgController;
which is trasformed to:
(...)
"use strict";
(...)
var exampleClass = function () {
function exampleClass() {
_classCallCheck(this, exampleClass);
}
_createClass(exampleClass, [{
key: "fun1",
value: function fun1() {
return new Promise(function ($return, $error) {
return $return();
}.bind(this));
}
}, {
key: "fun2",
value: function fun2() {
return new Promise(function ($return, $error) {
var channel;
return this.fun1().then(function ($await_2) {
try {
channel = $await_2;
function $Try_1_Post() {
return $return();
}
var $Try_1_Catch = function (e) {
try {
return $return(false);
} catch ($boundEx) {
return $error($boundEx);
}
}.bind(this);try {
return this.fun1().then($return, $Try_1_Catch);
} catch (e) {
$Try_1_Catch(e)
}
} catch ($boundEx) {
return $error($boundEx);
}
}.bind(this), $error);
}.bind(this));
}
}]);
return exampleClass;
}();
On IOS I get error
Strict mode does not allow function declarations in a lexically nested statement.
connected with code:
try {
function $Try_1_Post() {
return $return();
}
}
Any ideas how to fix it?
for...of inside async function inside an if blows up
export default async function blowUp(obj) {
if (obj) {
for (const fk of Object.keys(obj)) {
console.log(x);
}
}
}
Results in:
TypeError: src/fastasync.js: Cannot read property '0' of undefined
at Buffer._append (/my-serv/node_modules/babel-generator/lib/buffer.js:95:25)
at Buffer.append (/my-serv/node_modules/babel-generator/lib/buffer.js:72:10)
at Generator._append (/my-serv/node_modules/babel-generator/lib/printer.js:206:52)
at Generator.word (/my-serv/node_modules/babel-generator/lib/printer.js:131:10)
at Generator.Identifier (/my-serv/node_modules/babel-generator/lib/generators/types.js:38:8)
at /my-serv/node_modules/babel-generator/lib/printer.js:298:23
at Buffer.withSource (/my-serv/node_modules/babel-generator/lib/buffer.js:168:5)
at Generator.withSource (/my-serv/node_modules/babel-generator/lib/printer.js:189:15)
at Generator.print (/my-serv/node_modules/babel-generator/lib/printer.js:297:10)
at Generator.printJoin (/my-serv/node_modules/babel-generator/lib/printer.js:366:12)
Plugin breaks since babel-core 6.16
It fails here because apparently filename
has been renamed to sourceFileName
in 6.16+.
I can make a pull request for this change if you like
Cannot await non-Promises.
Using Babel 6, it appears right now that I cannot await
any non-Promise value. E.g.
(async () => { await 1 })()
throws Uncaught (in promise) TypeError: 1.then is not a function
. Is this by design, or is there something wrong with my setup?
Babel: Plugin no longer emits Function.prototype.$asyncbind since 6.0.34
As in the title. The plugin has been unusable since 6.0.34 for us because - although it seems to transform the async functions correctly - it doesn't provide the core runtime functionality ($asyncbind).
We only output $asyncbind to one file as per the docs:
{
"presets": ["es2015"],
"plugins": [
["fast-async", {
"runtimePattern": "src/index.js"
}]
]
}
In 6.0.34 this works. In 6.1+ the transform appears to work but src/index.js
doesn't receive $asyncbind
. This may be because src/index
itself doesn't contain any async functions itself?
can't call await on normal functions + can't use es2015 preset
The idea to use fast-async in Next.js came up, but there were these concerns:
- Apparently
fast-async
doesn't support callingawait
on normal functions that don't return a Promise. So if you, for example make a component which has astatic getInitialProps
instead ofstatic async getInitialProps
it will fail - would have to drop the es2015 preset to implement fast-async, since it conflicts with babel-plugin-transform-runtime ๐ข
Is that accurate? If these limitations do exist, is there a possibility/plan to address them? How do other users circumvent them?
for ... of produces `Cannot read property 'length' of undefined` error
However, this code is valid. I don't know why, but my own local setup doesn't compile it.
Content of package.json
:
{
"name": "fast-test",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"build": "babel -d lib src"
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-plugin-transform-es2015-spread": "^6.22.0",
"babel-plugin-transform-flow-strip-types": "^6.22.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-es2015": "^6.24.1",
"fast-async": "^6.3.0"
}
}
Content of .babelrc
:
{
"presets": [
"es2015"
],
"plugins": [
[
"fast-async",
{
"env": {
"log": false
},
"compiler": {
"promises": true,
"generators": false
},
"runtimePattern": "directive",
"useRuntimeModule": false
}
],
"transform-flow-strip-types",
"transform-es2015-spread",
"transform-object-rest-spread"
]
}
Content of src/index.js
:
async function on(id, cbk) {
if (!id || !cbk) return;
for (const sub of this.subs) {
if (sub.id === id && sub.cbk === cbk) return sub;
}
const sub = new Subscription(this, id, cbk);
this.subs.push(sub);
await sub.on();
return sub;
}
And the output is:
โณ ~/Projects/fast-test yarn build
yarn run v1.3.2
$ babel -d lib src
TypeError: src/index.js: Cannot read property 'length' of undefined
at Buffer._append (/Users/olebedev/Projects/fast-test/node_modules/babel-generator/lib/buffer.js:100:26)
at Buffer.append (/Users/olebedev/Projects/fast-test/node_modules/babel-generator/lib/buffer.js:72:10)
at Generator._append (/Users/olebedev/Projects/fast-test/node_modules/babel-generator/lib/printer.js:206:52)
at Generator.word (/Users/olebedev/Projects/fast-test/node_modules/babel-generator/lib/printer.js:131:10)
at Generator.Identifier (/Users/olebedev/Projects/fast-test/node_modules/babel-generator/lib/generators/types.js:38:8)
at /Users/olebedev/Projects/fast-test/node_modules/babel-generator/lib/printer.js:298:23
at Buffer.withSource (/Users/olebedev/Projects/fast-test/node_modules/babel-generator/lib/buffer.js:159:28)
at Generator.withSource (/Users/olebedev/Projects/fast-test/node_modules/babel-generator/lib/printer.js:189:15)
at Generator.print (/Users/olebedev/Projects/fast-test/node_modules/babel-generator/lib/printer.js:297:10)
at Generator.printJoin (/Users/olebedev/Projects/fast-test/node_modules/babel-generator/lib/printer.js:366:12)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
What I am doing wrong?
I've added workaround into babel-generator
and the result we surprised for me. Here to finction above, complied by babel in command line:
function on(id, cbk) {
return new Promise(function ($return, $error) {
var $Try_1_Finally = function ($Try_1_Exit) {
return function ($Try_1_Value) {
var $Try_2_Finally = function ($Try_2_Exit) {
return function ($Try_2_Value) {
if (_didIteratorError) {
throw _iteratorError;
}
return $Try_2_Exit && $Try_2_Exit.call(this, $Try_2_Value);
}.$asyncbind(this, $error);
}.$asyncbind(this);
var $Try_2_Catch = function ($exception_3) {
throw $exception_3;
}.$asyncbind(this, $Try_2_Finally($error));
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
return $Try_2_Finally()();
} catch ($exception_3) {
$Try_2_Catch($exception_3)
}
return $Try_1_Exit && $Try_1_Exit.call(this, $Try_1_Value);
}.$asyncbind(this, $error);
}.$asyncbind(this);
var _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, _sub, sub;
if (!id || !cbk) return $return();
_iteratorNormalCompletion = true;
_didIteratorError = false;
_iteratorError = undefined;
var $Try_1_Post = function () {
sub = new Subscription(this, id, cbk);
this.subs.push(sub);
return sub.on().then(function ($await_11) {
return $return(sub);
}.$asyncbind(this, $error), $error);
}.$asyncbind(this, $error);var $Try_1_Catch = function (err) {
_didIteratorError = true;
_iteratorError = err;
return $Try_1_Finally($Try_1_Post)();
}.$asyncbind(this, $Try_1_Finally($error));
try {
for (_iterator = this.subs[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
_sub = _step.value;
if (_sub.id === id && _sub.cbk === cbk) return $Try_1_Finally($return)(_sub);
}return $Try_1_Finally($Try_1_Post)();
} catch (err) {
$Try_1_Catch(err)
}
}.$asyncbind(this));
}
Compare it with nodent.mailed.me.uk's result, the difference is a huge. The question is, why so? And, how to setup babel to have a nice output like from nodent.mailed.me.uk ?
/cc @MatAtBread
try/finally not working?
I don't have detailed repro steps yet, but this seems to confuse fast-async:
try {
// some stuff
try {
// some more stuff
} finally {
// cleanup stuff
}
// super important stuff
} catch (error) {
// whatever
}
Basically, after "cleanup stuff" is run, it just falls off into the ether somewhere. "super important stuff" is never run.
About a webpack warning: Duplicate declaration
When using await
within for..of
Here is a warning
webpack: wait until bundle finished:
Duplicate declaration '_iterator = _isArray ? _iterator : _iterator[Symbol.iterator]()'
Duplicate declaration '_iterator = _isArray ? _iterator : _iterator[Symbol.iterator]()'
DONE Compiled successfully in 5303ms
I'm usingwebpack 2.3.3
Is there a way to remove this warning, I know this is just a Duplicate declaration
When using await
within for..of
, You can see this warning, like below:
async function loadCityList(Vue, store, city = "") {
if (store.getters.getCityList.length > 0) return store.getters.getCityList()
let cityList = await Vue.$api.supplier.getSupplierCityList({city})
if (cityList.length == 0) return cityList
let _cityList = []
for (let city of cityList) {
city = {
cityCode: city.city,
cityName: city.strCity,
baiduAreaCode: city.baiduAreaCode,
supplierList: []
}
let supplierList = await Vue.$api.supplier.getSupplierList({
"city": city.cityCode,
"userId": 0,
"weCharOpenId": Vue.$config.weCharOpenId
})
city.supplierList = supplierList.map(supplier => {
return {
city: city,
strVal1: supplier.strVal1,
supplierId: supplier.supplierId,
supplierLogo: supplier.supplierLogo,
supplierPic: supplier.supplierPic,
supplierCode: supplier.supplierCode,
supplierName: supplier.supplierName,
supplierFullName: supplier.supplierFullName,
}
})
_cityList.push(city)
}
after build:
function loadCityList(Vue, store) {
var $args = arguments;return new Promise(function ($return, $error) {
var city, cityList, _cityList, _loop, _iterator, _isArray, _i, _ref, _city;
city = $args.length > 2 && $args[2] !== undefined ? $args[2] : "";
if (store.getters.getCityList.length > 0) return $return(store.getters.getCityList());
return Vue.$api.supplier.getSupplierCityList({ city: city }).then(function ($await_3) {
cityList = $await_3;
if (cityList.length == 0) return $return(cityList);
_cityList = [];
_loop = function _loop(_city2) {
return new Promise(function ($return, $error) {
var supplierList;
_city2 = {
cityCode: _city2.city,
cityName: _city2.strCity,
baiduAreaCode: _city2.baiduAreaCode,
supplierList: [] };
return Vue.$api.supplier.getSupplierList({
"city": _city2.cityCode,
"userId": 0,
"weCharOpenId": Vue.$config.weCharOpenId
}).then(function ($await_4) {
supplierList = $await_4;
_city2.supplierList = supplierList.map(function (supplier) {
return {
city: _city2,
strVal1: supplier.strVal1,
supplierId: supplier.supplierId,
supplierLogo: supplier.supplierLogo,
supplierPic: supplier.supplierPic,
supplierCode: supplier.supplierCode,
supplierName: supplier.supplierName,
supplierFullName: supplier.supplierFullName
};
});
_cityList.push(_city2);
_city = _city2;
return $return();
}.$asyncbind(this, $error), $error);
}.$asyncbind(this));
};
// Here is the warning source...
// Duplicate declaration '_iterator = _isArray ? _iterator : _iterator[Symbol.iterator]()'
_iterator = cityList, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();
return Function.$asyncbind.trampoline(this, $Loop_1_exit, $Loop_1, $error, true)($Loop_1);
function $Loop_1() {
if (true) {
if (_isArray) {
if (_i >= _iterator.length) return [1];
_ref = _iterator[_i++];
} else {
_i = _iterator.next();
if (_i.done) return [1];
_ref = _i.value;
}
_city = _ref;
return _loop(_city).then(function ($await_5) {
return $Loop_1;
}.$asyncbind(this, $error), $error);
} else return [1];
}
function $Loop_1_exit() {
store.commit("updateCityList", _cityList);
store.commit("updateCurrentSupplierId", store.getters.getCurrentSupplierId || _cityList[0].supplierList[0].supplierId);
store.commit("updateCurrentCityId", store.getters.getCurrentSupplier.city.cityCode);
return $return(_cityList);
}
}.$asyncbind(this, $error), $error);
}.$asyncbind(this));
}
Here is my .babelrc:
{
"presets": [
["env", {
"modules": false,
"debug": false,
"useBuiltIns": true,
"loose": true,
"exclude": [
// for using fast-async
"transform-regenerator",
"transform-async-to-generator",
"transform-es2015-unicode-regex",
"transform-exponentiation-operator",
]
}],
// "stage-3" just use babel-plugin-transform-object-rest-spread
],
"plugins": [
"babel-plugin-transform-object-rest-spread",
// https://github.com/MatAtBread/fast-async
["fast-async", {
"env": {
"augmentObject": false,
"dontMapStackTraces": true,
"dontInstallRequireHook": true
},
"compiler": {
"promises": true,
"generators": false
},
"runtimePattern": null,
// using nodent-runtime like transform-runtime of babel
"useRuntimeModule": true
}],
// "transform-runtime"
],
"comments": false,
"env": {
"test": {
"presets": ["env", "stage-2"],
"plugins": [ "istanbul" ]
}
}
}
Destructuring still broken?
const { body: responseBody, status } = customerSearchResults;
const { _embedded = {} } = responseBody;
const { customers = [] } = _embedded || {};
const [customer] = customers || [];
const { id: customerId } = customer || {};
I end up with an error saying _embedded is not defined (probably on line 3 there if the sourcemap is to be believed).
It transpiles to this:
({ body: responseBody, status } = customerSearchResults);
({ _embedded = {} } = responseBody);
({ customers = [] } = _embedded || {});
[customer] = customers || [];
({ id: customerId } = customer || {});
Which doesn't look wrong, but somehow ends up failing, perhaps because of the 'use strict'?
Non-trivial destructuring initializers are broken
fast-async badly transforms destructuring initializers using anything other than the trivial forms const [a, b, c] = ...
or const { a, b, c } = ...;
inside any async functions, even if the RHS is not an await expression.
Further, it fails to parse array rest (ES2015, so not #6), and fails while transforming array eliding.
// work
async function trivialArray() {
const [a, b] = await Promise.resolve([1, 2]);
console.log(a, b);
}
async function trivialObject() {
const { a, b } = await Promise.resolve({ a: 1, b: 2 });
console.log(a, b);
}
// fails in parse
//async function arraySpread() {
// const [a, ...b, c] = await Promise.resolve([1, 2, 3, 4]);
// console.log(a, b, c);
//}
// fails in transform
//async function arrayElide() {
// const [,a,,b] = await Promise.resolve([1, 2, 3, 4]);
// console.log(a, b);
//}
// generate bad code, only declaring `var a, b`
async function rename() {
const { a, b: c } = await Promise.resolve({ a: 1, b: 2 });
console.log(a, c);
}
async function key() {
const { a, ['b']: c } = await Promise.resolve({ a: 1, b: 2 });
console.log(a, c);
}
async function nestedArray() {
const { a, b: [c, d] } = await Promise.resolve({ a: 1, b: [2, 3] });
console.log(a, c, d);
}
async function nestedObject() {
const { a, b: { c, d } } = await Promise.resolve({ a: 1, b: { c: 2, d: 3 } });
console.log(a, c, d);
}
async function indirect() {
const result = await Promise.resolve({ a: 1, b: 2 });
const { a, b: c } = result;
console.log(a, c);
}
Output is:
% babel --preset es2015 --plugins syntax-async-functions,fast-async async.js
Function.prototype.$asyncbind = <snip>
// work
function trivialArray() {
return new Promise(function ($return, $error) {
var a, b;
return Promise.resolve([1, 2]).then(function ($await_1) {
[a, b] = $await_1;
console.log(a, b);
return $return();
}.$asyncbind(this, $error), $error);
}.$asyncbind(this));
}
function trivialObject() {
return new Promise(function ($return, $error) {
var a, b;
return Promise.resolve({ a: 1, b: 2 }).then(function ($await_2) {
({ a, b } = $await_2);
console.log(a, b);
return $return();
}.$asyncbind(this, $error), $error);
}.$asyncbind(this));
}
// fails in parse
//async function arraySpread() {
// const [a, ...b, c] = await Promise.resolve([1, 2, 3, 4]);
// console.log(a, b, c);
//}
// fails in transform
//async function arrayElide() {
// const [,a,,b] = await Promise.resolve([1, 2, 3, 4]);
// console.log(a, b);
//}
// generate bad code, only declaring `var a, b`
function rename() {
return new Promise(function ($return, $error) {
var a, b;
return Promise.resolve({ a: 1, b: 2 }).then(function ($await_3) {
({ a, b: c } = $await_3);
console.log(a, c);
return $return();
}.$asyncbind(this, $error), $error);
}.$asyncbind(this));
}
function key() {
return new Promise(function ($return, $error) {
var a, undefined;
return Promise.resolve({ a: 1, b: 2 }).then(function ($await_4) {
({ a, ['b']: c } = $await_4);
console.log(a, c);
return $return();
}.$asyncbind(this, $error), $error);
}.$asyncbind(this));
}
function nestedArray() {
return new Promise(function ($return, $error) {
var a, b;
return Promise.resolve({ a: 1, b: [2, 3] }).then(function ($await_5) {
({ a, b: [c, d] } = $await_5);
console.log(a, c, d);
return $return();
}.$asyncbind(this, $error), $error);
}.$asyncbind(this));
}
function nestedObject() {
return new Promise(function ($return, $error) {
var a, b;
return Promise.resolve({ a: 1, b: { c: 2, d: 3 } }).then(function ($await_6) {
({ a, b: { c, d } } = $await_6);
console.log(a, c, d);
return $return();
}.$asyncbind(this, $error), $error);
}.$asyncbind(this));
}
function indirect() {
return new Promise(function ($return, $error) {
var result, a, b;
return Promise.resolve({ a: 1, b: 2 }).then(function ($await_7) {
result = $await_7;
({ a, b: c } = result);
console.log(a, c);
return $return();
}.$asyncbind(this, $error), $error);
}.$asyncbind(this));
}
Array rest gives error:
% babel --preset es2015 --plugins syntax-async-functions,fast-async async.js
SyntaxError: async.js: Unexpected token (10:16)
8 | }
9 | async function arraySpread() {
> 10 | const [a, ...b, c] = await Promise.resolve([1, 2, 3, 4]);
| ^
11 | console.log(a, b, c);
12 | }
13 | async function rename() {
Without fast-async
:
% babel --preset es2015 --plugins syntax-async-functions array_rest.js
async function test() {
const [a, ...b] = [1, 2, 3];
console.log(a, b);
}
Array elide gives error:
% babel --preset es2015 --plugins syntax-async-functions,fast-async async.js
TypeError: async.js: Cannot read property 'type' of null
at getDeclNames (/home/simon/code/xxx/node_modules/nodent/lib/arboriculture.js:2010:19)
at /home/simon/code/xxx/node_modules/nodent/lib/arboriculture.js:2014:70
at Array.reduce (native)
at getDeclNames (/home/simon/code/xxx/node_modules/nodent/lib/arboriculture.js:2014:32)
at /home/simon/code/xxx/node_modules/nodent/lib/arboriculture.js:2061:29
at treeWalker (/home/simon/code/xxx/node_modules/nodent/lib/parser.js:156:5)
at goDown (/home/simon/code/xxx/node_modules/nodent/lib/parser.js:122:9)
at down (/home/simon/code/xxx/node_modules/nodent/lib/parser.js:146:25)
at Object.base.Function (/home/simon/code/xxx/node_modules/acorn/dist/walk.js:269:4)
at down (/home/simon/code/xxx/node_modules/nodent/lib/parser.js:133:60)
SyntaxError: Strict mode does not allow function declarations in a lexically nested statement
fast-async compiled code throws SyntaxError: Strict mode does not allow function declarations in a lexically nested statement
in IOS 9.x.
.babelrc :
{
"plugins": [
[
"transform-runtime", {
"polyfill": false,
"regenerator": false
}
],
[
"fast-async", {
"env": {
"log": false
},
"compiler": {
"promises": true,
"generators": false,
"noRuntime": true
},
"runtimePattern": null,
"useRuntimeModule": true
}
]
]
}
source code:
async(ctx, next) => {
if (ctx.method != 'GET') {
const request = serializeRequest(ctx);
if (!requestLimits[request]) {
await next();
}
} else {
await next();
}
}
compiled code:
function (ctx, next) {
return new Promise(function ($return, $error) {
var request;
if (ctx.method != 'GET') {
request = serializeRequest(ctx);
if (!requestLimits[request]) {
return next().then(function ($await_5) {
try {
return $If_4.call(this);
} catch ($boundEx) {
return $error($boundEx);
}
}.bind(this), $error);
}
function $If_4() { // throws SyntaxError: Strict mode does not allow function declarations in a lexically nested statement
return $If_3.call(this);
}
return $If_4.call(this);
} else {
return next().then(function ($await_6) {
try {
return $If_3.call(this);
} catch ($boundEx) {
return $error($boundEx);
}
}.bind(this), $error);
}
function $If_3() {
return $return();
}
}.bind(this));
}
Could you fix this? Thanks very much for your hard work.
Error: unknown node of type "Literal" with constructor "Object"
I wanted to give a fast-async
a second shot but unfortunately it didn't work. I did nail down the problem to this piece of code though.
let foo = async () => {
for(let bar of []) {
await Promise.resolve();
}
};
Full error:
/code/babel-fast-async-test/node_modules/babel-core/lib/transformation/file/index.js:600
throw err;
^
ReferenceError: /code/babel-fast-async-test/index.js: unknown node of type "Literal" with constructor "Object"
at Generator.print (/code/babel-fast-async-test/node_modules/babel-generator/lib/printer.js:279:13)
at Generator.MemberExpression (/code/babel-fast-async-test/node_modules/babel-generator/lib/generators/expressions.js:228:10)
at /code/babel-fast-async-test/node_modules/babel-generator/lib/printer.js:298:23
at Buffer.withSource (/code/babel-fast-async-test/node_modules/babel-generator/lib/buffer.js:151:5)
at Generator.withSource (/code/babel-fast-async-test/node_modules/babel-generator/lib/printer.js:189:15)
at Generator.print (/code/babel-fast-async-test/node_modules/babel-generator/lib/printer.js:297:10)
at Generator.AssignmentExpression (/code/babel-fast-async-test/node_modules/babel-generator/lib/generators/expressions.js:189:8)
at /code/babel-fast-async-test/node_modules/babel-generator/lib/printer.js:298:23
at Buffer.withSource (/code/babel-fast-async-test/node_modules/babel-generator/lib/buffer.js:151:5)
at Generator.withSource (/code/babel-fast-async-test/node_modules/babel-generator/lib/printer.js:189:15)
My .babelrc
:
{
"presets": ["es2015-node6"],
"plugins": ["transform-decorators-legacy", "transform-class-properties", "transform-es2015-modules-commonjs", "transform-strict-mode", "transform-es2015-spread", "transform-es2015-destructuring", "transform-es2015-block-scoping", ["fast-async", {
"compiler": {
"sourcemap": true
}
}]]
}
To reproduce:
wget http://x.rushbase.net/ad01410a94ea35c0d57d86ddfe4eedd4da29c877/babel-fast-async-test.zip
cd babel-fast-async-test
npm install
node -r babel-register index.js
await on literal value causes error
In such code:
const getSearchCount = () => {
return await {
repoCount: 100,
codeCount: 20
};
};
fast-async will generate wrong code such as (copied from console):
function getSearchCount(keyword) {
return new Promise(function ($return, $error) {
return {
repoCount: 100,
codeCount: 20
}.then($return, $error);
}.$asyncbind(this));
}
which obviously leads to error (object does not have then
method)
"await is a reserved word"
I will get right to the point:
.babelrc
:
{
"presets": [
["@babel/env", {
"targets": {
"node": "current"
}
}]
],
"plugins": [
"module:fast-async",
["babel-plugin-module-resolver", {
"alias": {
"BIRD3": "./src"
}
}],
["@babel/plugin-proposal-class-properties", {
"loose": true
}],
["@babel/plugin-transform-react-jsx", {
"pragma": "h",
"pragmaFrag": "fragment",
"throwIfNamespace": false
}]
]
}
Error:
{ SyntaxError: /Users/Ingwie/Work/DragonsInn/BIRD3/test2.js: await is a reserved word (8:14)
6 | init() {
7 | try {
> 8 | let a = await someFunction();
| ^
9 | let b = await someFunction();
10 | console.log("Math:" + (a+b))
11 | } catch(e) throw e;
at _class.raise (/usr/local/lib/node_modules/@babel/core/node_modules/@babel/parser/lib/index.js:4021:15)
at _class.checkReservedWord (/usr/local/lib/node_modules/@babel/core/node_modules/@babel/parser/lib/index.js:7146:12)
at _class.parseIdentifierName (/usr/local/lib/node_modules/@babel/core/node_modules/@babel/parser/lib/index.js:7111:12)
at _class.parseIdentifier (/usr/local/lib/node_modules/@babel/core/node_modules/@babel/parser/lib/index.js:7103:21)
at _class.parseExprAtom (/usr/local/lib/node_modules/@babel/core/node_modules/@babel/parser/lib/index.js:6296:25)
at _class.parseExprAtom (/usr/local/lib/node_modules/@babel/core/node_modules/@babel/parser/lib/index.js:3717:52)
at _class.parseExprSubscripts (/usr/local/lib/node_modules/@babel/core/node_modules/@babel/parser/lib/index.js:6006:21)
at _class.parseMaybeUnary (/usr/local/lib/node_modules/@babel/core/node_modules/@babel/parser/lib/index.js:5985:21)
at _class.parseExprOps (/usr/local/lib/node_modules/@babel/core/node_modules/@babel/parser/lib/index.js:5894:21)
at _class.parseMaybeConditional (/usr/local/lib/node_modules/@babel/core/node_modules/@babel/parser/lib/index.js:5866:21)
pos: 94,
loc: Position { line: 8, column: 14 },
code: 'BABEL_PARSE_ERROR' }
Versions:
[email protected] ~/W/D/BIRD3 $ babel --version
7.1.5 (@babel/core 7.1.5)
[email protected] ~/W/D/BIRD3 $ cat package.json | grep babel
"@babel/cli": "^7.1.5",
"@babel/core": "^7.1.5",
"@babel/plugin-proposal-class-properties": "^7.1.0",
"@babel/plugin-transform-object-super": "^7.0.0",
"@babel/plugin-transform-react-jsx": "^7.0.0",
"@babel/preset-env": "^7.1.5",
"babel-loader": "^8.0.2",
"babel-plugin-module-resolver": "^3.1.1",
[email protected] ~/W/D/BIRD3 $ cat package.json | grep fast-async
"fast-async": "^7",
[email protected] ~/W/D/BIRD3 $ node --version
v11.1.0
What I am trying to do is, to test various transformer plugins on the CLI before adding them to my WebPack build. I wanted to test fast-async
to see if it transforms async
and await
in the way that I want.
While I am at it: How do I tell the plugin to only include the NoDent runtime once for many files, so it doesn't blow up the whole build in the end?
Well, I tried removing various entries from the .babelrc
and even tried without a .babelrc
entirely, with the plugin just specified on the CLI, and get the same error each and every time. What am I doing wrong here? :)
Also, the code I am trying to transpile:
async function someFunction() {
return 1;
}
class Foo {
init() {
try {
let a = await someFunction();
let b = await someFunction();
console.log("Math:" + (a+b))
} catch(e) throw e;
}
}
new Foo().init();
Crashes if compiler options are missing
There are no defaults for state.opts.compiler
Crash happens here (plugin.js):
Object.keys(state.opts.compiler).forEach(function(k){
compilerOpts[k] = state.opts.compiler[k] ;
}) ;
Issues with source maps
- Source maps are not enabled by default
- The first babel run on the file does not have working source maps
To reproduce the second:
git clone https://github.com/Rush/fasy-async-sourcemaps-test
cd fasy-async-sourcemaps-test
npm install
npm test
You will see both first and second run:
> [email protected] test /code/fasy-async-sourcemaps-test
> rm -f ~/.babel.json && node run-fastasync.js && node run-fastasync.js
Error
at Foo.$ForStatement_1_loop (/code/fasy-async-sourcemaps-test/test.js:165:31)
at Function.boundThen [as then] (/code/fasy-async-sourcemaps-test/test.js:132:21)
at /code/fasy-async-sourcemaps-test/test.js:170:35
at Foo.<anonymous> (/code/fasy-async-sourcemaps-test/test.js:174:12)
at boundThen (/code/fasy-async-sourcemaps-test/test.js:132:21)
at Foo.liveBackup (/code/fasy-async-sourcemaps-test/test.js:149:14)
at Object.<anonymous> (/code/fasy-async-sourcemaps-test/test.js:216:11)
at Module._compile (module.js:556:32)
at loader (/code/fasy-async-sourcemaps-test/node_modules/babel-register/lib/node.js:143:5)
at Object.require.extensions.(anonymous function) [as .js] (/code/fasy-async-sourcemaps-test/node_modules/babel-register/lib/node.js:153:7)
Error
at $ForStatement_1_loop (/code/fasy-async-sourcemaps-test/test.js:165:31)
at Foo.$ForStatement_1_next (/code/fasy-async-sourcemaps-test/test.js:161:26)
at Foo.<anonymous> (/code/fasy-async-sourcemaps-test/test.js:167:54)
at then (/code/fasy-async-sourcemaps-test/test.js:125:126)
at process._tickCallback (internal/process/next_tick.js:103:7)
at Module.runMain (module.js:592:11)
at run (bootstrap_node.js:394:7)
at startup (bootstrap_node.js:149:9)
at bootstrap_node.js:509:3
Error
at $ForStatement_1_loop (/code/fasy-async-sourcemaps-test/test.js:165:31)
at $ForStatement_1_next (/code/fasy-async-sourcemaps-test/test.js:161:26)
at /code/fasy-async-sourcemaps-test/test.js:167:54
at then (/code/fasy-async-sourcemaps-test/test.js:125:126)
at process._tickCallback (internal/process/next_tick.js:103:7)
at Module.runMain (module.js:592:11)
at run (bootstrap_node.js:394:7)
at startup (bootstrap_node.js:149:9)
at bootstrap_node.js:509:3
foo
Error
at Foo.$ForStatement_1_loop (/code/fasy-async-sourcemaps-test/test.js:8:17)
at Function.boundThen [as then] (/code/fasy-async-sourcemaps-test/test.js:132:21)
at /code/fasy-async-sourcemaps-test/test.js:5:1
at Foo.<anonymous> (/code/fasy-async-sourcemaps-test/test.js:5:1)
at boundThen (/code/fasy-async-sourcemaps-test/test.js:132:21)
at Foo.liveBackup (/code/fasy-async-sourcemaps-test/test.js:5:1)
at Object.<anonymous> (/code/fasy-async-sourcemaps-test/test.js:18:11)
at Module._compile (module.js:556:32)
at loader (/code/fasy-async-sourcemaps-test/node_modules/babel-register/lib/node.js:143:5)
at Object.require.extensions.(anonymous function) [as .js] (/code/fasy-async-sourcemaps-test/node_modules/babel-register/lib/node.js:153:7)
Error
at $ForStatement_1_loop (/code/fasy-async-sourcemaps-test/test.js:8:17)
at Foo.$ForStatement_1_next (/code/fasy-async-sourcemaps-test/test.js:5:1)
at Foo.<anonymous> (/code/fasy-async-sourcemaps-test/test.js:9:5)
at then (/code/fasy-async-sourcemaps-test/test.js:125:126)
at process._tickCallback (internal/process/next_tick.js:103:7)
at Module.runMain (module.js:592:11)
at run (bootstrap_node.js:394:7)
at startup (bootstrap_node.js:149:9)
at bootstrap_node.js:509:3
Error
at $ForStatement_1_loop (/code/fasy-async-sourcemaps-test/test.js:8:17)
at $ForStatement_1_next (/code/fasy-async-sourcemaps-test/test.js:5:1)
at /code/fasy-async-sourcemaps-test/test.js:9:5
at then (/code/fasy-async-sourcemaps-test/test.js:125:126)
at process._tickCallback (internal/process/next_tick.js:103:7)
at Module.runMain (module.js:592:11)
at run (bootstrap_node.js:394:7)
at startup (bootstrap_node.js:149:9)
at bootstrap_node.js:509:3
foo
In contrast the bluebird version works fine:
node run-bluebird.js
broken interaction with babel modules transform
To reproduce:
// foo.js
export default async function bar() {}
bar.SOMETHING = 3
// .babelrc
{
"plugins": [
"transform-es2015-modules-commonjs",
"fast-async"
]
}
And run npm install fast-async babel-cli babel-plugin-transform-es2015-modules-commonjs
.
Running ./node_modules/.bin/babel-node foo.js
then gives:
bar.SOMETHING = 3;
^
ReferenceError: bar is not defined
Await above for...of causes compilation error
This only occurs in combination with transform-es2015-for-of
in loose mode.
This code:
async function run(filePath) {
const fileContents = await readFileAsync(filePath, 'utf8');
for (const field of fileContents) {
}
}
Compiles to:
Duplicate declaration '_iterator = _isArray ? _iterator : _iterator[Symbol.iterator]()'
import _default from 'nodent-runtime';
function run(languages) {
return new Promise(function ($return, $error) {
var fileContents, _iterator, _isArray, _i, _ref, field;
return readFileAsync(filePath, 'utf8').then(function ($await_1) {
fileContents = $await_1;
for ({
_iterator = fileContents
_isArray = Array.isArray(_iterator)
_i = 0
_iterator = _isArray ? _iterator : _iterator[Symbol.iterator]()
};;) {
if (_isArray) {
if (_i >= _iterator.length) break;
_ref = _iterator[_i++];
} else {
_i = _iterator.next();
if (_i.done) break;
_ref = _i.value;
}
field = _ref;
}
return $return();
}.$asyncbind(this, $error), $error);
}.$asyncbind(this));
}
Notice the error in the top line and the very odd for()
syntax.
.babelrc:
{
"plugins": [
['transform-es2015-for-of', {loose: true}],
'syntax-async-functions',
['fast-async', {
useRuntimeModule: 'nodent-runtime'
}]
]
}
ReferenceError: unknown node of type "Literal" with constructor "Object"
Hi!
A user of Neutrino reported an issue with their project when they updated their dependencies (neutrinojs/neutrino#984) that upon creating a reduced testcase, appears to be due to fast-async
/ nodent-compiler
regression.
The exception no longer occurs if nodent-compiler is rolled back to v3.1.8
(eg using yarn's resolutions
feature). The first version of nodent-compiler
that triggers the exception is v3.2.0
.
STR:
- Clone https://github.com/edmorley/testcase-fast-async-unknown-node
yarn
yarn babel testcase.js
Expected:
Command completes successfully, or else if the testcase's syntax is invalid, a helpful error message is output.
Actual:
ReferenceError: testcase.js: unknown node of type "Literal" with constructor "Object"
at Generator.print (...\node_modules\babel-generator\lib\printer.js:279:13)
at Generator.MemberExpression (...\node_modules\babel-generator\lib\generators\expressions.js:229:10)
at ...\node_modules\babel-generator\lib\printer.js:298:23
at Buffer.withSource (...\node_modules\babel-generator\lib\buffer.js:159:28)
at Generator.withSource (...\node_modules\babel-generator\lib\printer.js:189:15)
at Generator.print (...\node_modules\babel-generator\lib\printer.js:297:10)
at Generator.AssignmentExpression (...\node_modules\babel-generator\lib\generators\expressions.js:190:8)
at ...\node_modules\babel-generator\lib\printer.js:298:23
at Buffer.withSource (...\node_modules\babel-generator\lib\buffer.js:159:28)
at Generator.withSource (...\node_modules\babel-generator\lib\printer.js:189:15)
Does this work with babel-preset-es2017?
6.1.1: regeneratorRuntime is not defined
I have a 'regeneratorRuntime is not defined' bug with 6.1.1 (everything was fine with previous versions)
My .babelrc is similar to the minimal .babelrc example :
{ "plugins": ["fast-async"] }
errors to console
Hello! Can this plugin output unhandled error to err stream?
async function someFunctionWithUncatchedError(){
throw new Error(123); //nothing output from hire to err stream/ silent break function and very hard to debug code
try {
throw new Error(123); //this error will be handled
}
catch(er){
console.error(er)
}
}
someFunctionWithUncatchedError();
Promise is undefined
How do I use this for IE9? I have in .babelrc
:
["fast-async", {
"compiler": {
"promises": false
},
"useRuntimeModule": true
}],
and even import nodent-runtime
in my main file, but I keep seeing that Promise is undefined
in IE. Could you please explain how to use it :(( it's so frustrating -- do I need to update webpack config to provide global Promise
?
Cannot append Element node to non-array
Hi, I'm trying to switch from transform-async-to-module-method
to fast-async
, and I bumped into this error. I reduced the code to this minimal example:
test.js:
export const A = '';
class B {
async f() {
await g();
}
}
.babelrc:
{
"presets": [
"es2015",
"stage-0"
],
"plugins": [
["fast-async", {
"runtimePattern": "main.js"
}],
]
}
And it produces the following error:
Error: test.js: Cannot append Element node to non-array
at Object.append (/home/diego/repos/brainiac-www/node_modules/nodent/lib/parser.js:87:23)
at /home/diego/repos/brainiac-www/node_modules/nodent/lib/arboriculture.js:2190:34
at Array.forEach (native)
at /home/diego/repos/brainiac-www/node_modules/nodent/lib/arboriculture.js:2189:32
at Object.treeWalker (/home/diego/repos/brainiac-www/node_modules/nodent/lib/parser.js:156:5)
at hoistDeclarations (/home/diego/repos/brainiac-www/node_modules/nodent/lib/arboriculture.js:2136:16)
at asyncTransforms (/home/diego/repos/brainiac-www/node_modules/nodent/lib/arboriculture.js:359:9)
at asynchronize (/home/diego/repos/brainiac-www/node_modules/nodent/lib/arboriculture.js:352:9)
at NodentCompiler.asynchronize (/home/diego/repos/brainiac-www/node_modules/nodent/lib/arboriculture.js:2657:20)
at PluginPass.Program (/home/diego/repos/brainiac-www/node_modules/fast-async/plugin.js:36:14)
Is this a bug in fast-async
, or perhaps something wrong in my code?
Thanks!
How to create Bluebird promises from async functions
Given the below code, how to configure fast-async/nodent to return bluebird promises?
import Promise from 'bluebird';
async function foo() {
return 'bar';
}
// where .delay is provided by bluebird
foo().delay(3000).then(() => {
});
Babel v7: Env Preset + nodent breaks in Babel generator
I have another exception I got in a pretty trivial case.
Code:
async function executeTasks(tasks) {
for (const taskName of tasks) {
try {
await executeCommands()
} catch (error) {
console.error("Error")
}
}
}
Babelrc:
{
"presets": [
[ "@babel/env", { "exclude": ["transform-regenerator", "transform-async-to-generator"] } ]
],
"plugins": [
"module:./src/transformAsyncToPromises.js"
]
}
Command Line:
node_modules/.bin/babel --config-file ./.babelrc-test --no-babelrc async-for-of.js
Exception:
TypeError: Cannot read property 'length' of undefined
at Buffer._append (/Users/swerner/Workspace/open-source/babel-preset-edge/node_modules/@babel/generator/lib/buffer.js:115:26)
at Buffer.append (/Users/swerner/Workspace/open-source/babel-preset-edge/node_modules/@babel/generator/lib/buffer.js:81:10)
at Generator._append (/Users/swerner/Workspace/open-source/babel-preset-edge/node_modules/@babel/generator/lib/printer.js:202:52)
at Generator.word (/Users/swerner/Workspace/open-source/babel-preset-edge/node_modules/@babel/generator/lib/printer.js:126:10)
at Generator.Identifier (/Users/swerner/Workspace/open-source/babel-preset-edge/node_modules/@babel/generator/lib/generators/types.js:43:8)
at /Users/swerner/Workspace/open-source/babel-preset-edge/node_modules/@babel/generator/lib/printer.js:315:23
at Buffer.withSource (/Users/swerner/Workspace/open-source/babel-preset-edge/node_modules/@babel/generator/lib/buffer.js:178:28)
at Generator.withSource (/Users/swerner/Workspace/open-source/babel-preset-edge/node_modules/@babel/generator/lib/printer.js:182:15)
at Generator.print (/Users/swerner/Workspace/open-source/babel-preset-edge/node_modules/@babel/generator/lib/printer.js:314:10)
at Generator.printJoin (/Users/swerner/Workspace/open-source/babel-preset-edge/node_modules/@babel/generator/lib/printer.js:382:12)
I modified the generator a bit to catch this case:
_proto._append = function _append(str, line, column, identifierName, filename) {
if (this._map && str[0] !== "\n") {
this._map.mark(this._position.line, this._position.column, line, column, identifierName, filename);
}
// Hot fix
if (str == null) {
str = "[XXXXX]"
}
...
Generated output with fix:
"use strict";
function executeTasks(tasks) {
return new Promise(function ($return, $error) {
var $Try_1_Finally = function ($Try_1_Exit) {
return function ($Try_1_Value) {
try {
var $Try_3_Finally = function ($Try_3_Exit) {
return function ($Try_3_Value) {
try {
if (_didIteratorError) {
throw _iteratorError;
}
return $Try_3_Exit && $Try_3_Exit.call(this, $Try_3_Value);
} catch ($boundEx) {
return $error($boundEx);
}
}.bind(this);
}.bind(this);
var $Try_3_Catch = function ($exception_4) {
try {
throw $exception_4;
} catch ($boundEx) {
return $Try_3_Finally($error)($boundEx);
}
}.bind(this);
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
return $Try_3_Finally([XXXXX])();
} catch ($exception_4) {
$Try_3_Catch($exception_4)
}
return $Try_1_Exit && $Try_1_Exit.call(this, $Try_1_Value);
} catch ($boundEx) {
return $error($boundEx);
}
}.bind(this);
}.bind(this);
var _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, taskName;
_iteratorNormalCompletion = true;
_didIteratorError = false;
_iteratorError = undefined;
var $Try_1_Post = function () {
try {
return $return();
} catch ($boundEx) {
return $error($boundEx);
}
};
var $Try_1_Catch = function (err) {
try {
_didIteratorError = true;
_iteratorError = err;
return $Try_1_Finally($Try_1_Post)();
} catch ($boundEx) {
return $Try_1_Finally($error)($boundEx);
}
};
try {
_iterator = tasks[Symbol.iterator]();
var $Loop_5_trampoline;
function $Loop_5_step() {
_iteratorNormalCompletion = true;
return $Loop_5;
}
function $Loop_5() {
if (!(_iteratorNormalCompletion = (_step = _iterator.next()).done)) {
taskName = _step.value;
var $Try_2_Post = function () {
try {
return $Loop_5_step;
} catch ($boundEx) {
return $Try_1_Catch($boundEx);
}
};
var $Try_2_Catch = function (error) {
try {
console.error("Error");
return $Try_2_Post();
} catch ($boundEx) {
return $Try_1_Catch($boundEx);
}
};
try {
return Promise.resolve(executeCommands()).then(function ($await_7) {
try {
return $Try_2_Post();
} catch ($boundEx) {
return $Try_2_Catch($boundEx);
}
}, $Try_2_Catch);
} catch (error) {
$Try_2_Catch(error)
}
} else return [1];
}
return ($Loop_5_trampoline = function (q) {
while (q) {
if (q.then) return void q.then($Loop_5_trampoline, $Try_1_Catch);
try {
if (q.pop) {
if (q.length) return q.pop() ? $Loop_5_exit.call(this) : q;else q = $Loop_5_step;
} else q = q.call(this);
} catch (_exception) {
return $Try_1_Catch(_exception);
}
}
}.bind(this))($Loop_5);
function $Loop_5_exit() {
return $Try_1_Finally($Try_1_Post)();
}
} catch (err) {
$Try_1_Catch(err)
}
});
}
The problematic code is at line 35:
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
return $Try_3_Finally([XXXXX])();
} catch ($exception_4) {
$Try_3_Catch($exception_4)
}
Do you have any idea what's wrong?
incorrect code when this is used in async function
This code:
public async loadBundle() {
return new Promise((resolve, reject) => {
if (this.xhr) {
this.xhr.abort()
this.xhr = undefined
}
this.xhr = $.ajax({
url: "some url",
dataType: "script",
success: () => {
resolve()
},
error: (jqXHR, textStatus, errorThrown) => {
reject()
},
})
})
}
converted to:
loadBundle(bundleID) {
return new Promise(function ($return, $error) {
return $return(new Promise((resolve, reject) => {
if (this.xhr) {
this.xhr.abort();
this.xhr = undefined;
}
this.xhr = $.ajax({
url: "some url",
dataType: "script",
success: () => {
resolve()
},
error: (jqXHR, textStatus, errorThrown) => {
reject()
}
});
}));
});
and this
is always undefined here because return new Promise(function ($return, $error) {
steals this
.
package.json:
"@babel/core": "^7.1.6",
"@babel/plugin-proposal-class-properties": "^7.1.0",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
"@babel/plugin-transform-react-constant-elements": "^7.0.0",
"@babel/plugin-transform-react-inline-elements": "^7.0.0",
"@babel/preset-env": "^7.1.6",
"@babel/preset-react": "^7.0.0",
"@babel/preset-typescript": "^7.1.0",
"fast-async": "^7.0.6",
babel.config.js:
{
compact: false,
presets: [
['@babel/preset-env', {
targets: ['Since 2018'],
exclude: ['transform-regenerator']
}],
['@babel/preset-react', { development: isDev }],
['@babel/preset-typescript', { isTSX: true, allExtensions: true }]
],
plugins: [
'@babel/proposal-class-properties',
'@babel/proposal-object-rest-spread',
'module:fast-async',
'add-module-exports',
'inline-react-svg',
'add-react-displayname',
]
}
Does not transpile defaults in object destructuring
config
{
"presets": [
[
"env",
{
"targets": {
"node": "6.10"
},
"exclude": [
"transform-regenerator",
"transform-async-to-generator"
]
}
]
],
"plugins": [
"syntax-async-functions",
[
"fast-async",
{
"useRuntimeModule":true
}
],
"add-module-exports",
[
"transform-object-rest-spread",
{
"useBuiltIns": true
}
]
]
}
Input:
const {
bar = async bar => bar
} = {}
async function test ({
foo = async foo => foo
}, cb = async foo => foo) {
console.log(foo, cb)
}
output
"use strict";
var _nodentRuntime = require("nodent-runtime");
var _nodentRuntime2 = _interopRequireDefault(_nodentRuntime);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const {
bar = async bar => bar
} = {};
function test({
foo = async foo => foo
}, cb = foo => new Promise(function ($return, $error) {
return $return(foo);
}.$asyncbind(this))) {
return new Promise(function ($return, $error) {
console.log(foo, cb);
return $return();
}.$asyncbind(this));
}
Thanks!
I think fast-async and rest-spread is not incompatible
I think fast-async
and rest spread
is not incompatible
the error sample :
origin es file
(props) => {
let { ...others } = props
}
babel options
module.exports = {
"presets": [ "es2015", "stage-2" ],
"plugins": [
[require("fast-async"), { runtimePattern: 'directive' }]
]
}
exception stack info
"TypeError: Cannot read property 'name' of undefined
at fast-async\node_modules\nodent\lib\arboriculture.js:2004:63
at Array.map (native)
at getDeclNames (fast-async\node_modules\nodent\lib\arboriculture.js:2004:34)
at fast-async\node_modules\nodent\lib\arboriculture.js:2050:29
at treeWalker (fast-async\node_modules\nodent\lib\parser.js:156:5)
at goDown (fast-async\node_modules\nodent\lib\parser.js:122:9)
at down (fast-async\node_modules\nodent\lib\parser.js:146:25)
at Object.__dirname.1.base.Function (fast-async\node_modules\nodent\node_modules\acorn\dist\walk.js:269:4)
at down (fast-async\node_modules\nodent\lib\parser.js:133:60)
at Object.__dirname.1.base.FunctionDeclaration (fast-async\node_modules\nodent\node_modules\acorn\dist\walk.js:253:10)"
Losing const
I've noticed we lost const in async functions when we use fast-async.
export async function indexPost ({ id }, opts) {
const input = { ids: [id] }
await indexPosts(input, opts)
return { post: { id } }
}
// bluebird
let indexPost = exports.indexPost = (() => {
var _ref41 = (0, _bluebird.coroutine)(function* ({ id }, opts) {
const input = { ids: [id] };
yield indexPosts(input, opts);
return { post: { id } };
});
return function indexPost(_x22, _x23) {
return _ref41.apply(this, arguments);
};
})();
// fast-async
function indexPost({ id }, opts) {
return new Promise(function ($return, $error) {
var input;
input = { ids: [id] };
return indexPosts(input, opts).then(function ($await_109) {
return $return({ post: { id } });
}.$asyncbind(this, $error), $error);
}.$asyncbind(this));
}
My babel config looks like this
{
"babel": {
"presets": [
[
"env",
{
"targets": {
"node": "6.10"
},
"exclude": [
"transform-regenerator",
"transform-async-to-generator"
]
}
]
],
"plugins": [
"syntax-async-functions",
[
"fast-async",
{
"useRuntimeModule": true
}
],
"add-module-exports",
[
"transform-object-rest-spread",
{
"useBuiltIns": true
}
]
]
}
}
[bug] Errors when transforming code with for-of loops
Hi!
Seems that some of the more recent version introduces errors during processing. Either babel-v6 is erroring out with unknown node of type "Literal" with constructor "Object"
or there are warnings by nodent-transform
: arboriculture.js:2327: Duplicate declaration '_iterator = _isArray ? _iterator : _iterator[Symbol.iterator]()'
Simple async code seems to work while it breaks with for-of-loops (works with "normal" for-in loops) and try-catch blocks. This is my reduced example which throws:
async function executeTasks(tasks) {
for (const taskName of tasks) {
try {
await executeCommands()
} catch (error) {
console.error("Error")
}
}
}
fast-async not working when awaiting non-promise
Consider this small code. It is working with Babel implementation.
async function returnsFive() {
var three = 3;
var threeP = await three;
return threeP+2;
}
returnsFive().then(k=>console.log(k), e=>console.error("err", e))
See babel repl.
With fast-async, I get
index.js:1362 err TypeError: three.then is not a function
That's not good.
I cannot right now find a formal specification for async/await, so I am not sure which implementation is "correct".
Runtime included when not needed
The runtime is inlined even when the file does not include any async call.
add options to select which parts of the runtime will be included
When I load fast-async
as a babel
plugin with the following configuration {compiler: {noRuntime: false, promises: true}}
, the runtime is included in the output file. Currently that runtime is 286 lines long (before minification) and includes things that I don't use, such as support for lazy thenables and the entire Zousan
library. I suspect that only a small part of that is actually needed in my case. Is it possible to make fast-async
include only a subset of the runtime?
test failed with latest dependencies
$ npm test
> [email protected] test /Users/undozen/github/fa
> cd tests && npm i && node .
npm WARN package.json [email protected] No repository field.
npm WARN package.json [email protected] No README data
[email protected] node_modules/colors
[email protected] node_modules/fast-async
โโโ [email protected] ([email protected], [email protected], [email protected])
[email protected] node_modules/babel-plugin-syntax-async-functions
โโโ [email protected] ([email protected])
[email protected] node_modules/babel-core
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected]
โโโ [email protected] ([email protected])
โโโ [email protected] ([email protected], [email protected])
โโโ [email protected] ([email protected])
โโโ [email protected] ([email protected], [email protected], [email protected])
โโโ [email protected] ([email protected], [email protected], [email protected], [email protected], [email protected])
โโโ [email protected] ([email protected], [email protected], [email protected], [email protected])
โโโ [email protected]
โโโ [email protected] ([email protected], [email protected], [email protected], [email protected])
โโโ [email protected] ([email protected])
#### To run the tests you need to npm install babel-core. This additional module is only required for testing, not deployment.
Starting tests...
'npm install babel-plugin-transform-async-to-generator babel-preset-es2015' to compare against babel plugin 'transform-async-to-generator'
'npm install babel-plugin-transform-async-to-module-method babel-preset-es2015 bluebird coroutine' to compare against babel plugin 'transform-async-to-module-method'
Transforming with fast-async
TypeError: unknown: Cannot read property 'end' of undefined
at /Users/undozen/github/fa/tests/node_modules/babel-core/node_modules/babel-generator/lib/whitespace.js:50:19
at Whitespace._findToken (/Users/undozen/github/fa/tests/node_modules/babel-core/node_modules/babel-generator/lib/whitespace.js:99:30)
at Whitespace._findToken (/Users/undozen/github/fa/tests/node_modules/babel-core/node_modules/babel-generator/lib/whitespace.js:101:19)
at Whitespace._findToken (/Users/undozen/github/fa/tests/node_modules/babel-core/node_modules/babel-generator/lib/whitespace.js:101:19)
at Whitespace._findToken (/Users/undozen/github/fa/tests/node_modules/babel-core/node_modules/babel-generator/lib/whitespace.js:101:19)
at Whitespace._findToken (/Users/undozen/github/fa/tests/node_modules/babel-core/node_modules/babel-generator/lib/whitespace.js:101:19)
at Whitespace._findToken (/Users/undozen/github/fa/tests/node_modules/babel-core/node_modules/babel-generator/lib/whitespace.js:101:19)
at Whitespace._findToken (/Users/undozen/github/fa/tests/node_modules/babel-core/node_modules/babel-generator/lib/whitespace.js:101:19)
at Whitespace._findToken (/Users/undozen/github/fa/tests/node_modules/babel-core/node_modules/babel-generator/lib/whitespace.js:101:19)
at Whitespace.getNewlinesAfter (/Users/undozen/github/fa/tests/node_modules/babel-core/node_modules/babel-generator/lib/whitespace.js:49:22)
[Bug] 6.3.2 - Error: Cannot find module '@babel/helper-module-imports'
@babel/helper-module-imports
is being used in plugin.js
but is not present in package.json
's dependencies.
Error: Cannot find module '@babel/helper-module-imports'
at Function.Module._resolveFilename (module.js:547:15)
at Function.Module._load (module.js:474:25)
at Module.require (module.js:596:17)
at require (internal/module.js:11:18)
at module.exports (*****/fast-async/plugin.js:10:25)
[bug] infinite recursion (stack overflow) with $super$N helper
I've got some transpiled ode that looks like this:
disconnectedCallback() {
return new Promise(function ($return, $error) {
if (this.$super$1('disconnectedCallback')) this.$super$1('disconnectedCallback').call(this);
and it looks like $super$1('disconnectedCallback').call(this)
calls the exact same disconnectedCallback
method in an infinite loop.
I'm not sure if this is a fast-async problem, I think probably not, because $super$1
just calls native super. But it is fast-async output, so thought I'd post just in case.
Gonna investigate...
Use Promise from babel-transform-runtime?
babel-transform-runtime
transpiles Promise
in source code to _Promise
which is ultimately the Promise
polyfill from core-js
.
Is it possible to make fast-async
use transform-runtime promises?
Currently, when I set the fast-async option compiler.promises
to true, it result in Promise
appearing in the output.
Then, I thought that if I change the ordering of plugins so that fast-async
runs before transform-runtime
, that transform-runtime
would handle these Promise
s, but this isn't the case. transform-runtime
is leaving those in the output unpolyfilled. If I try swapping the order of the two plugins, no luck.
If I set compiler.promises
to false, then I see Nodent's Promise polyfill included (which is extra duplication).
A possible workaround could be that I can have a separate Babel step using only fast-async
to convert async functions on first pass with promises: true
, then the second pass of Babel would catch those Promises. This will obviously take more time, but the output will be better (I think?).
Benchmarks?
I know this isn't an 'issue', but I've been battling against this myself. Here's my scenaro:
- Code calls a function to lookup value (async)
- If value is cached, return straight from cache.
- If value not cached, go fetch (websocket call actual async)
In short, I'm using an async code path that is potentially async in some places - but actually 99% of the time - totally sync. What I've been finding is that Promise.resolve(cachedValue) would bounce off the queue, causing massive slowdown. Your module is a massive improvement I find over the naive Promise based approach.
Been trying to benchmark a scenario where I do 200,000 operations, and finding that I'm not getting a massive uplift from fast-async. I'm wondering if this is a Node 6.4 or Babel improvement, because I only get a material difference when using babel-plugin-transform-bluebird - but even then it's nowhere near as fast as a pure sync solution - there's a serious amount of performance being lost.
- fast-async / Native promises - 2758msec
- fast-async / transform-bluebird - 1688msec
- transform-async-to-generator / native promises - 7257msec
- transform-async-to-generator / transform-bluebird - 1750msec
In short, async-to-generator with the transform-bluebird seems to achieve most of the same effect, however, if I modify the such that I remove any reference to async/await and only use the sync path I get:
- no async/await - 763msec
The mysteries I'm facing:
- Why does using transform-bluebird help at all? I'm not seeing any promises in the generated code with the default parameters.
- Is there any option to set to reduce the overhead? I'm guessing the time differential of circa 1 - 1.3 seconds is basically the overhead of 200,000 of the method call setups/promise unrolling behaviour. Just looking to confirm I've not missed a setting that might help.
async functions are omitted when called from a regular function
I was experimenting with fast-async
and babel
and I got the following unexpected behavior: Suppose that you have the following input file:
async function dummy() {
console.log("test");
}
// execute dummy in the background:
dummy();
If I transpile it with babel
, the output is empty. When I change the last line to
dummy().then();
then everything works as expected.
I have configured babel
with plugins: ["fast-async", {spec: true}]
without any preset.
What babel options to get the promise transformation ?
I'm trying this:
var options = {
presets: ['es2015','stage-0'],
plugins: [["fast-async",{compiler:{promises:true}}]]
};
but it somehow doesn't output promises
Edit: Ah I guess I do need to exclude the transform-async-to-generator plugin
Edit2: ok I got it to work by excluding transform-async-to-generator (manually specifying the plugins I need from stage-0)
It seems nodent/fast-async doesn't handle async methods though ?
class A
{
async f()
{
return 5;
}
}
Edit3: well in the end that unhandled method bug was my real problem, letting stage-0 in presets is okay
Transforming constants with "arguments" object property names?
console.log({
arguments: [4567],
});
async function foo() {
console.log({
arguments: [1234],
});
}
foo();
The output is:
{ arguments: [ 4567 ] }
{ '$args': [ 1234 ] }
Await inside for loop does not work
async liveBackup(files) {
/* some other code here */
for(let file of files) {
await execFileAsync('touch', [backupFile(file.fullPath)]);
}
}
{ TypeError: /code/app/lib/api/machines.js: Duplicate declaration "file" (This is an error on an internal node. Probably an internal error)
at File.buildCodeFrameError (/code/app/node_modules/babel-core/lib/transformation/file/index.js:431:15)
at Scope.checkBlockScopedCollisions (/code/app/node_modules/babel-traverse/lib/scope/index.js:397:27)
at Scope.registerBinding (/code/app/node_modules/babel-traverse/lib/scope/index.js:579:16)
at Scope.registerDeclaration (/code/app/node_modules/babel-traverse/lib/scope/index.js:483:14)
at Object.BlockScoped (/code/app/node_modules/babel-traverse/lib/scope/index.js:185:28)
It works fine with babel's async-to-module-method.
Runtime as module
Following the discussion in MatAtBread/nodent#60
FYI, noRuntime is nice, but it is a bit slower, mainly because .bind(this) is slow compared to $asyncbind(this), and the need to wrap async bodies in a try...catch causes de-optimization.
I think it would be nice to have an option to require
the runtime as a module. Currently the choices are: directive, everywhere or in some file matching a regexp.
Something like babel-runtime
:
const fn = async function(){}
Transforms into
require('nodent-runtime');
var fn = function fn() {
return new Promise(function ($return, $error) {
return $return();
}.$asyncbind(this));
};
And throw if nodent-runtime
is not in the package dependencies.
Options not working
I can't get any of the options for this plugin to work...
For example, with this configuration:
{
"plugins":
["fast-async", {
"runtimePattern": "test-input\\.js"
}]
}
I get:
Error: Plugin 1 specified in "/www/derby-boilerplate/.babelrc" provided an invalid property of "runtimePattern"
I'm running Babel 6.10.1.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.