UNPKG

8.58 kBMarkdownView Raw
1fast-async
2==========
3
4'fast-async' is a _Babel v6.x.x_ plugin that implements the ES7 keywords `async` and `await` using syntax transformation
5at compile-time, rather than generators.
6
7The main reason for using 'fast-async' as opposed to Babel's default implementation of async/await is
8performance (https://github.com/MatAtBread/nodent#performance) - it's 3-4 times faster in a browser/node, and
9as much as 10 times faster on a mobile browsers, mainly due to avoiding generators (and therefore regenerator).
10
11There's a simple test (that just makes sure the plugin works and generates code that runs). More complete
12test coverage is included with nodent.
13
14Because 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.
15
16For _Babel v5.x.x_ install fast-async@1.0.3
17
18> v6.1.x
19fast-async@>=6.1.0 can use nodent v2 or v3 (and acorn v3 or v4). Nodent v3 has the option of generating code with Promises which needs no runtime at all, at the cost of size and speed. v6.1.x can also reference the runtime via an import (useRuntimeModule option), rather than include the source inline.
20
21Install
22-------
23```bash
24npm install fast-async --save
25```
26
27Usage
28-----
29
30Just include the plugin to the babel options. Minimal `.babelrc` example:
31```js
32{
33 "plugins": ["fast-async"]
34}
35```
36
37That's all. Neither `babel-plugin-transform-runtime` nor `babel-polyfill` required. Your application, once compiled, will probably needs nodent's runtime = see [below](#runtimepattern).
38
39With options:
40```js
41{
42 "plugins": [
43 ["fast-async", {
44 "env": {
45 "augmentObject": false,
46 "dontMapStackTraces": true,
47 "dontInstallRequireHook": true
48 },
49 "compiler": {
50 "promises": true,
51 "generators": false
52 },
53 "runtimePattern":null,
54 "useRuntimeModule":false
55 }]
56 ]
57}
58```
59
60The option `spec` sets the compiler up to produce the most spec-compatible output (at the expense of some performance) by using the `wrapAwait`, `noRuntime` and `promises` options. Since `noRuntime` is specified, no runtime options are required.
61
62```js
63{
64 "plugins": [
65 ["fast-async", {
66 "spec":true
67 }]
68 ]
69}
70```
71
72
73Test
74----
75From the installation directory (e.g. node_modules/fast-async):
76```bash
77npm test
78```
79Options
80-------
81The plugin accepts the following options object, which itself is optional, as are all members. These are based on the options in nodent,
82but since much of the parsing is done by Babel some are unused.
83
84```js
85env:{
86 log:function(string), // Supplied routine to emit transformation warnings. Default: console.log
87 augmentObject:false, // Add the nodent utilities asyncify() and isThenable() to Object.prototype
88 dontMapStackTraces:true, // Don't install the stack trace hook that maps line numbers (default: true)
89 dontInstallRequireHook:false // Don't transform all JS files as they are loaded into node (default: true)
90},
91compiler:{
92 promises:true, // Use nodent's "Promises" mode. Set to false if your execution environment does not support Promises.
93 generators:false // Transform into 'Generators' (sub-optimal, but it works)
94},
95runtimePattern:null, // See below
96useRuntimeModule:false // See below
97```
98
99For more information on the compiler options, see [ES7 and Promises](https://github.com/matatbread/nodent#es7-and-promises) in the nodent documentation.
100
101> 6.1.x
102The dontMapStackTraces now defaults to `true` as having both nodent and babel map stack traces doesn't work well
103
104runtimePattern
105--------------
106By default, fast-async will put the nodent runtime into every file containing an `async` function or `await` expression.
107If your project is made up of more than one file, the constant redefinition of the runtime is a waste of time and space. You can
108specify that you want the runtime in particular file(s) by setting the 'runtimePattern' to a regular expression (in quotes).
109Only files that match the regular expression will have the runtime defined (which is global, so you only need it once).
110
111Note: At least one of the file(s) matching the "runtimePattern" must use either `await` or `async` as the runtime function (or `require('nodent-runtime')` if you set `"useRuntimeModule":true`) is only included for files that reference it.
112
113For example:
114
115```js
116"babel": {
117 "plugins": [
118 "syntax-async-functions",
119 ["fast-async",{
120 "runtimePattern":"test-input\\.js"
121 }]
122 ]
123}
124```
125Alternatively, if you set runtimePattern to `"directive"`, the statement `"use runtime-nodent";` will be replaced with the runtime during compilation.
126
127> v6.1.x
128If you specify the option `"useRuntimeModule":true`, the runtime is not included directly as source, but via an import of [nodent-runtime](https://github.com/MatAtBread/nodent-runtime), which is typically resolved to `require()` by babel. The nodent-runtime module must be added as a dependency in your target project. The runtime need only be included once in your entire project, and should precede any code that uses async or await.
129
130Useful Links
131------------
132
133* [nodent](https://github.com/MatAtBread/nodent)
134* [Babel plugins](http://babeljs.io/docs/advanced/plugins/)
135
136Online performance checkers:
137
138* [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)
139* [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
140* [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