Skip to content

Commit

Permalink
Merge pull request #95 from MatAtBread/extract-compiler
Browse files Browse the repository at this point in the history
Extract compiler into separate module 'nodent-compiler'
  • Loading branch information
matAtWork authored Jul 12, 2017
2 parents f595f7b + e66b734 commit da7a1e6
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 4,078 deletions.
53 changes: 43 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Contents
* [Why Nodent?](#why-nodent)
* [Installation](#installation)
* [Command\-Line usage](#command-line-usage)
* [Use within Node](#use-within-your-node-scripts)
* [Node.js usage](#node-js-usage)
* [ES7 and Promises](#es7-and-promises)
* [Use within a browser](#use-within-a-browser)
* [async and await syntax](#async-and-await-syntax-and-usage)
Expand Down Expand Up @@ -86,7 +86,7 @@ Installation

Command-Line usage
==================
You can invoke and run a nodented JavaScript file from the command line (although for Node apps it's much easier using the [JS transpiler](#use-within-your-node-scripts)). To load, compile and run your JS file (containing `async` and `await`), use:
You can invoke and run a nodented JavaScript file from the command line (although for Node apps it's much easier using the [JS transpiler](#automatic-transpilation)). To load, compile and run your JS file (containing `async` and `await`), use:

./nodent.js myNodentedFile.js

Expand Down Expand Up @@ -133,12 +133,16 @@ Code generation options:
| --es6target | Compile code assuming an ES6 target (as of v3.0.8, this only requires support for arrow functions)
| --noextensions | Don't allow nodent's extensions to the ES7 specification [more info...](#differences-from-the-es7-specification)

Use within your Node scripts
Node.js usage
============================

Automatic transpilation
------------

There is no need to use the command line at all if you want to do is use `async` and `await` in your own scripts then just `require('nodent')()`. Files are transformed if they have a `use nodent` directive at the top, or have the extension ".njs". Existing files ending in '.js' _without_ a `use nodent...` directive are untouched and are loaded and executed unchanged.

ES7 and Promises
----------------
### ES7 and Promises

Nodent can generate code that implements `async` and `await` using basic ES5 JavaScript, Promises (via Nodent's built-in library, a third party library or module, or an ES5+/6 platform) or Generators (ES6). Using the directive:

'use nodent';
Expand All @@ -152,23 +156,40 @@ Within your package.json, you can have named sets of pre-defined options, which
'use nodent-generators';
'use nodent-engine';

### Which one should you use?
#### Which one should you use?
All the implementations work with each other - you can mix and match. If you're unsure as to which will suit your application best, or want to try them all out `'use nodent';` will use a 'default' configuration you can determine in your application's package.json. See [Advanced Configuration](#advanced-configuration) for details.

#### Shipping a self-contained app to a browser, Node <=0.10.x or other unknown environment
##### Shipping a self-contained app to a browser, Node <=0.10.x or other unknown environment
`use nodent-es7` - it's the most compatible as it doesn't require any platform support such as Promises or Generators, and works on a wide range of desktop and mobile browsers.

#### Shipping an app or module within Node, npm or [modern browsers supporting Promises](http://kangax.github.io/compat-table/es6/#test-Promise)
##### Shipping an app or module within Node, npm or [modern browsers supporting Promises](http://kangax.github.io/compat-table/es6/#test-Promise)
`use nodent-promises` provides the most compatibility between modules and apps. If your module or library targets Node earlier than v4.1.x, you should install a Promise library (e.g. rsvp, when, bluebird) or use `nodent.Thenable` to expose the Promise API. In promises mode, there is no need for a runtime at all. Specifying the option `use nodent-promises {"noRuntime":true}` will generate pure ES5 code at the cost of some loss in performance and increase in code size.

> **v2.x** users: `nodent.EagerThenable()` is still defined, but as of v3 is the same as the `Thenable` implementation.
#### Generators
##### Generators
`use nodent-generators` generates code which is reasonably easy to follow, but is best not used for anything beyond experimentation as it requires an advanced browser on the client-side, or Node v4.x.x. The performance and memory overhead of generators is poor - currently (Node v6.6.0) averaging 3.5 times slower compared to the es7 with 'lazyThenables'.

#### Engine
##### Engine
`use nodent-engine` does _not_ transpile standard ES7 async/await constructs, but only transpiles the additional non-standard features provided by nodent - await anywhere, async getters, async return and throw. At the time of writing, not many runtimes implement async and await - Chrome v53 does with command line flags, and Edge 14 are examples. On Chrome, performance is better than generators, but not quite as good as Promises, and still less than half the speed of ES7 mode. In promises mode, there is no need for a runtime at all. Specifying the option `use nodent-engine {"noRuntime":true}` will generate pure ES5 code at the cost of some loss in performance and increase in code size.

Programmatical usage within scripts
-------------

To compile code programmatically you should use require([`nodent-compiler`](https://github.com/MatAtBread/nodent-compiler)). This module is a standalone compiler that has:

- no require hook (it does not intercept .js files as they are loaded into Node)
- no runtime (it does not implement any functions required to run transpiled code)
- no pollution (because it has no runtime, it does not add async-specific bindings on `Function.prototype`, a global error handler, stack source-mapping)

Example usage:

```javascript
var NodentCompiler = require('nodent-compiler');
var compiler = new NodentCompiler() ;
var es5ReadySourceCode = compiler.compile(sourceCode, filename, { sourcemap:false, promises: true, noRuntime: true, es6target: true });
```

Use within a browser
====================

Expand Down Expand Up @@ -562,6 +583,18 @@ This execution case was pointed out by https://github.com/jods4 - many thanks.
Changelog
==========

12-Jul-17 v3.1.0

This version splits the CLI, require hook and options parsing (`use nodent` directive, package.json options) from the core compiler.

_If your code monkey patches the internals of nodent, it may no longer work, as the core compiler has been moved into a submodule._

- The core compiler is now in [`nodent-compiler`](https://github.com/MatAtBread/nodent-compiler).
- The runtime remains in [`nodent-runtime`](https://github.com/MatAtBread/nodent-runtime)
- The CLI (which invokes the compiler), require hook (which intercepts .js files loaded into node and sets up the runtime environment) remiain here, in `nodent`.

If you are not requiring individual components within `nodent` or otherwise dependent on the internal structure, no changes will be required.

04-Jul-17 v3.0.20

- Fix issue with '.' after a template string.
Expand Down
1 change: 1 addition & 0 deletions covers/asyncfunction.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module.exports = function(nodent,config) {
config.promises = 'Promise' in global ;
if (!('log' in config) || config.log===false)
config.log = Nothing ;
config.sourcemap = false ;

function AsyncFunction() {
var params = [].slice.call(arguments,0,-1) ;
Expand Down
Loading

0 comments on commit da7a1e6

Please sign in to comment.