Skip to content

Commit ee6107a

Browse files
committed
Implement compiler flags. Update README. Tidy up tests
1 parent 049656d commit ee6107a

File tree

5 files changed

+82
-39
lines changed

5 files changed

+82
-39
lines changed

README.md

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
fast-async
22
==========
33

4-
'fast-async' is a _Babel v6.x.x_ plugin that implements the ES7 keywords `async` and `await` using syntax transformation
4+
'fast-async' is a _Babel v6.x.x_ plugin that implements the ES7 keywords `async` and `await` using syntax transformation
55
at compile-time rather than generators.
66

7-
The main reason for using 'fast-async' as opposed to Babel's default implementation of async/await is
7+
The main reason for using 'fast-async' as opposed to Babel's default implementation of async/await is
88
performance (https://github.com/MatAtBread/nodent#performance) - it's 3-4 times faster in a browser/node, and
99
as much as 10 times faster on a mobile browsers, mainly due to avoiding generators (and therefore regenerator).
1010

1111
There's a simple test (that just makes sure the plugin works and generates code that runs). More complete
1212
test coverage is included with nodent.
1313

14-
fast-async (via nodent) can generate code suitable for use in early Browsers with no Promise support (as well as no generators),
15-
and has various options for turning sourcemaps on/off and controlling code generation, however for now it simply chooses some defaults.
16-
1714
Because Babel parses the code, the ES7 extensions possible with nodent (`await` anywhere, `async return` and `async throw`) are not supported, however full implementation of `async function` containing `await` expressions is implemented.
1815

1916
For _Babel v5.x.x_ install [email protected]
@@ -22,13 +19,31 @@ Install
2219
-------
2320

2421
npm install fast-async
25-
22+
2623
Test
2724
----
2825
From the installation directory (e.g. node_modules/fast-async):
2926

3027
npm test
3128

29+
Options
30+
-------
31+
The plugin accepts the following options object, which itself is optional, as are all members. These are based on the options in nodent,
32+
but since much of the parsing is done by Babel some are unused.
33+
34+
env:{
35+
log:function(string), // Supplied routine to emit transformation warnings. Default: console.log
36+
augmentObject:false, // Add the nodent utilities asyncify() and isThenable() to Object.prototype
37+
dontMapStackTraces:false, // Don't install the stack trace hook that maps line numbers
38+
asyncStackTrace:false, // Provide async stack traces
39+
dontInstallRequireHook:false // Don't transform all JS files as they are loaded into node
40+
},
41+
compiler:{
42+
promises:true, // Use nodent's "Promises" mode. Set to false if your execution environment does not support Promises.
43+
generators:false // Transform into 'Generators'.
44+
}
45+
46+
For more information on the compiler options, see [ES7 and Promises](https://github.com/matatbread/nodent#es7-and-promises) in the nodent documentation.
3247

3348
Useful Links
3449
------------
@@ -41,4 +56,3 @@ Online performance checkers:
4156
* [nodent](http://nodent.mailed.me.uk/#function%20pause%28%29%20{%0A%20%20%20%20return%20new%20Promise%28function%20%28%24return%2C%20%24error%29%20{%0A%20%20%20%20%20%20%20%20setTimeout%28function%20%28%29%20{%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%24return%280%29%3B%0A%20%20%20%20%20%20%20%20}%2C%200%29%3B%0A%20%20%20%20}%29%3B%0A}%0A%0Aasync%20function%20doNothing%28%29%20{%0A%20%20%20%20return%3B%0A}%0A%0Aasync%20function%20test%28%29%20{%0A%20%20%20%20var%20t%20%3D%20Date.now%28%29%3B%0A%20%20%20%20for%20%28var%20j%20%3D%200%3B%20j%20%3C%2050%3B%20j%2B%2B%29%20{%0A%20%20%20%20%20%20%20%20for%20%28var%20i%20%3D%200%3B%20i%20%3C%201000%3B%20i%2B%2B%29%20{%0A%20%20%20%20%20%20%20%20%20%20%20%20await%20doNothing%28%29%3B%0A%20%20%20%20%20%20%20%20}%0A%20%20%20%20%20%20%20%20await%20pause%28%29%3B%0A%20%20%20%20}%0A%20%20%20%20return%20Date.now%28%29%20-%20t%3B%0A}%0A%0Atest%28%29.then%28alert%29%3B%0A) 632ms (and shave off another 100ms by selecting 'Pure ES5' mode)
4257
* [babel](https://babeljs.io/repl/#?experimental=true&evaluate=true&loose=false&spec=false&code=function%20pause%28%29%20{%0A%20%20%20%20return%20new%20Promise%28function%20%28%24return%2C%20%24error%29%20{%0A%20%20%20%20%20%20%20%20setTimeout%28function%20%28%29%20{%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%24return%280%29%3B%0A%20%20%20%20%20%20%20%20}%2C%200%29%3B%0A%20%20%20%20}%29%3B%0A}%0A%0Aasync%20function%20doNothing%28%29%20{%0A%20%20%20%20return%3B%0A}%0A%0Aasync%20function%20test%28%29%20{%0A%20%20%20%20var%20t%20%3D%20Date.now%28%29%3B%0A%20%20%20%20for%20%28var%20j%20%3D%200%3B%20j%20%3C%2050%3B%20j%2B%2B%29%20{%0A%20%20%20%20%20%20%20%20for%20%28var%20i%20%3D%200%3B%20i%20%3C%201000%3B%20i%2B%2B%29%20{%0A%20%20%20%20%20%20%20%20%20%20%20%20await%20doNothing%28%29%3B%0A%20%20%20%20%20%20%20%20}%0A%20%20%20%20%20%20%20%20await%20pause%28%29%3B%0A%20%20%20%20}%0A%20%20%20%20return%20Date.now%28%29%20-%20t%3B%0A}%0A%0Atest%28%29.then%28alert%2Calert%29%3B%0A) 1877ms - 3x slower
4358
* [traceur](https://google.github.io/traceur-compiler/demo/repl.html#%2F%2F%20Options%3A%20--annotations%20--array-comprehension%20--async-functions%20--async-generators%20--exponentiation%20--export-from-extended%20--for-on%20--generator-comprehension%20--member-variables%20--proper-tail-calls%20--require%20--symbols%20--types%20%0Afunction%20pause%28%29%20{%0A%20%20%20%20return%20new%20Promise%28function%20%28%24return%2C%20%24error%29%20{%0A%20%20%20%20%20%20%20%20setTimeout%28function%20%28%29%20{%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%24return%280%29%3B%0A%20%20%20%20%20%20%20%20}%2C%200%29%3B%0A%20%20%20%20}%29%3B%0A}%0A%0Aasync%20function%20doNothing%28%29%20{%0A%20%20%20%20return%3B%0A}%0A%0Aasync%20function%20test%28%29%20{%0A%20%20%20%20var%20t%20%3D%20Date.now%28%29%3B%0A%20%20%20%20for%20%28var%20j%20%3D%200%3B%20j%20%3C%2050%3B%20j%2B%2B%29%20{%0A%20%20%20%20%20%20%20%20for%20%28var%20i%20%3D%200%3B%20i%20%3C%201000%3B%20i%2B%2B%29%20{%0A%20%20%20%20%20%20%20%20%20%20%20%20await%20doNothing%28%29%3B%0A%20%20%20%20%20%20%20%20}%0A%20%20%20%20%20%20%20%20await%20pause%28%29%3B%0A%20%20%20%20}%0A%20%20%20%20return%20Date.now%28%29%20-%20t%3B%0A}%0A%0Atest%28%29.then%28alert%2Calert%29%3B%20%0A) 2488ms - 4x slower
44-

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
22
"name": "fast-async",
3-
"version": "6.0.0",
3+
"version": "6.0.1",
44
"dependencies": {
5-
"acorn-es7-plugin": "^1.0.7",
6-
"nodent": "^2.2.3"
5+
"acorn-es7-plugin": "^1.0.8",
6+
"nodent": "^2.2.4"
77
},
88
"description": "fast-async/await transformer Babel plugin",
99
"main": "plugin.js",

plugin.js

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,9 @@ try {
2323

2424

2525
module.exports = function (types) {
26+
debugger ;
2627
var logger = console.log.bind(console) ;
27-
var nodent = require('nodent')({log:logger}) ;
28-
var opts = nodent.parseCompilerOptions('"use nodent-promises";',nodent.log) ;
29-
opts.babelTree = true ;
30-
var binder = nodent.parse("Function.prototype.$asyncbind="+Function.prototype.$asyncbind.toString().replace(/[\s]+/g," "),null,opts);
31-
var asyncbind = binder.ast.body[0];
28+
var nodent = require('nodent') ;
3229

3330
return {
3431
// Lifted from https://github.com/babel/babel/blob/master/packages/babel-plugin-syntax-async-functions/src/index.js#L3,
@@ -38,10 +35,24 @@ module.exports = function (types) {
3835
},
3936
visitor: {
4037
Program:function Program(path,state) {
38+
var envOpts = state.opts.env || {} ;
39+
if (!('log' in envOpts)) envOpts.log = logger ;
40+
if (!('dontInstallRequireHook' in envOpts)) envOpts.dontInstallRequireHook = true ;
41+
var compiler = nodent(envOpts) ;
42+
43+
var opts = compiler.parseCompilerOptions('"use nodent-promises";',compiler.log) ;
44+
opts.babelTree = true ;
45+
46+
for (var k in opts) {
47+
if (state.opts && state.opts.compiler && (k in state.opts.compiler))
48+
opts[k] = state.opts.compiler[k] ;
49+
}
4150
var pr = { origCode:state.file.code, filename:"", ast:path.node } ;
42-
nodent.asynchronize(pr,undefined,opts,nodent.log) ;
51+
52+
var binder = compiler.parse("Function.prototype.$asyncbind="+Function.prototype.$asyncbind.toString().replace(/[\s]+/g," "),null,opts);
53+
var asyncbind = binder.ast.body[0];
54+
compiler.asynchronize(pr,undefined,opts,compiler.log) ;
4355
pr.ast.body.unshift(asyncbind) ;
44-
nodent.prettyPrint(pr,{}) ;
4556
}
4657
}
4758
};

tests/test-input.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@ async function test() {
2121
return "Finished in "+(Date.now() - t)+"ms";
2222
}
2323

24-
test().then(done,done) ;
24+
test().then(resolve,reject) ;

tests/test.js

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
1-
/* Test running for fast-async babel plugin
2-
*
1+
/* Test running for fast-async babel plugin
2+
*
33
* Open the file ./test-input.js and compile it using the fast-async plugin and run it.
4-
*
4+
*
55
* It should output 'return: true'
66
*/
77

88
require('colors');
99
console.log("#### To run the tests you need to \"npm install babel-core\" and optionally (if you want to compare performance):");
10-
console.log("#### "+"npm install babel-preset-2015 babel-transform-async-to-module-method babel-transform-async-to-generator bluebird coroutine".yellow);
11-
console.log("#### These additional modules are only required for testing, not deployment.\n\nStarting tests...")
10+
console.log("#### "+"npm install babel-preset-es2015 babel-transform-async-to-module-method babel-transform-async-to-generator bluebird coroutine".yellow);
11+
console.log("#### These additional modules are only required for testing, not deployment.")
12+
13+
console.log("#### "+"As of Nov-05 2015 the babel-transform-async* plugins appear to be broken".cyan)
14+
15+
console.log("\nStarting tests...");
16+
1217
try {
13-
global.Promise = global.Promise || global.Promise = require('bluebird') ;
18+
global.Promise = global.Promise || require('bluebird') ;
1419
} catch (ex) {
1520
global.Promise = global.Promise || require('nodent').Thenable ;
1621
}
@@ -19,39 +24,52 @@ var testCode = require('fs').readFileSync(__dirname+'/test-input.js').toString()
1924
var babel = require("babel-core") ;
2025

2126
var transformers = {
22-
'fast-async':{plugins:[require('../plugin.js')]}
27+
'fast-async':{plugins:[[require('../plugin.js'),{env:{dontMapStackTraces:true},compiler:{promises:false}}]]},
2328
};
2429

2530
var requires ;
2631
try {
27-
requires = ['babel-plugin-transform-async-to-generator','babel-preset-2015'] ;
32+
requires = ['babel-plugin-transform-async-to-generator','babel-preset-es2015'] ;
2833
requires.map(require) ;
2934
transformers['transform-async-to-generator'] = {"presets": ["es2015"],plugins:['transform-async-to-generator']} ;
30-
} catch (ex) {
35+
} catch (ex) {
3136
/* not installed */
3237
console.log("'"+("npm install "+requires.join(' ')).yellow+"' to compare against babel plugin 'transform-async-to-generator'") ;
3338
}
3439

3540
try {
36-
requires = ['babel-plugin-transform-async-to-module-method','babel-preset-2015','bluebird','coroutine'] ;
41+
requires = ['babel-plugin-transform-async-to-module-method','babel-preset-es2015','bluebird','coroutine'] ;
3742
requires.map(require) ;
3843
transformers['transform-async-to-module-method'] = {"presets": ["es2015"],plugins:[["transform-async-to-module-method",{module: 'bluebird',method: 'coroutine'}]]}
39-
} catch (ex) {
44+
} catch (ex) {
4045
/* not installed */
4146
console.log("'"+("npm install "+requires.join(' ')).yellow+"' to compare against babel plugin 'transform-async-to-module-method'") ;
4247
}
4348

4449
var keys = Object.keys(transformers) ;
4550
(function nextTest(i){
46-
if (i===0) {
47-
global.regeneratorRuntime = require("babel-core/node_modules/babel-runtime/regenerator").default;
51+
try {
52+
if (i===1) {
53+
console.log("Loading babel-runtime/regenerator") ;
54+
global.regeneratorRuntime = require("babel-core/node_modules/babel-runtime/regenerator").default;
55+
}
56+
console.log("Transforming with "+keys[i]);
57+
var t = babel.transform(testCode, transformers[keys[i]]);
58+
var f = new Function("resolve,reject",t.code) ;
59+
f(function(result){
60+
console.log(keys[i],result.green) ;
61+
next() ;
62+
},function(error){
63+
console.log(keys[i],(error.stack || error).red) ;
64+
next() ;
65+
}) ;
66+
function next() {
67+
i++ ;
68+
if (i<keys.length)
69+
nextTest(i) ;
70+
}
71+
} catch (ex) {
72+
console.error(ex.stack.red) ;
73+
next() ;
4874
}
49-
var t = babel.transform(testCode, transformers[keys[i]]);
50-
var f = new Function("done",t.code) ;
51-
f(function(result){
52-
console.log(keys[i],result) ;
53-
i++ ;
54-
if (i<keys.length)
55-
nextTest(i) ;
56-
}) ;
5775
})(0) ;

0 commit comments

Comments
 (0)