es6-transpiler.js
es6 -> es5
status
Beta
Goal
- different output than traceur-compiler:
- no runtime library (only polyfills if needed)
- no try/catch for block binding
- spread:
* via
.concat
* should respect Iterator protocol
* spread is operator, not a function - minimal count of temporary variables
- termination stage for temporary variables
- es6 RegExp support
- and others
- output should support Closure Compiler
- line-to-line input/output mapping
Supported
- classes
- destructuring (with default values)
- block binding (let / const)
- loops: fresh lexical environment per iteration
- function default parameters and rest
- arrow functions
- spread (with iterator protocol)
- for-of (with iterator protocol)
- array comprehensions (with iterator protocol)
- string templates (with tags support)
- object literals (partial support see: Not supported)
- binary/octal numericLiteral
- unicode code point escapes
- RegExp:
- 'y' flag support (in runtime via polyfill)
- 'u' flag support:
- full transpiler-time support: [negative] astral symbols (surrogate pairs) ranges, \D, \W, '.' etc captures astral symbols
- partial runtime support see: Not supported
Static scope analysis and transpilation of ES6 block scoped const
and let
variables to ES3 based on olov/defs.
Not supported
- modules
- generators / generator comprehensions
- symbols
- object literals:
- RegExp:
- 'u' flag in runtime (via polyfill) for the newly generated patterns:
- \D, \W, '.' etc not supported
- negative astral symbols (surrogate pairs) ranges
Supported iterator protocol
var obj = {a: 1, b: 2, c: 3};
var Symbol_iterator = typeof Symbol !== 'undefined' && Symbol.iterator || "@@iterator";
obj[Symbol_iterator] = function() {
var iterableObject = this;
var keys = ["a", "b", "c"];
return {
next: function() {
var currentKey = keys.shift();
return {
value: currentKey ? iterableObject[currentKey] : void 0
, done: !currentKey
}
}
}
}
Installation
Install using npm
npm install es6-transpiler
Or just using Grunt task (see below).
Usage
For the output code works you need an implementation of Object.create in the target browser.
You can get it here: es5-shim or copy and past this code:
if(!Object.create)Object.create = function(_prototype) {//[Warning!!!]This is PURE and UNSAFE implementation of Object.create
var Type = function () {};
Type.prototype = _prototype;
var _object = new Type();
_object.__proto__ = _prototype;
return _object;
};
Grunt task
Grunt task can be fount here: https://github.com/termi/grunt-es6-transpiler
Install:
npm install grunt-es6-transpiler
Usage:
grunt.loadNpmTasks('grunt-es6-transpiler');
grunt.initConfig({
"es6-transpiler": {
test: {
src: 'test.js'
, dest: 'test.es5.js'
}
},
})
Gulp task
Gulp task can be fount here: https://github.com/sindresorhus/gulp-es6-transpiler
Install:
npm install --save-dev gulp-es6-transpiler
Usage:
var gulp = require('gulp');
var es6transpiler = require('gulp-es6-transpiler');
gulp.task('default', function () {
gulp.src('src/app.js')
.pipe(es6transpiler())
.pipe(gulp.dest('dist'));
});
In console
Run it as es6toes5 <input file>
. Or node --harmony es6toes5 <input file>
. Also you can run a compiled es5 version node build/es5/es6toes5 <input file>
.
The errors (if any) will go to stderr, the transpiled source to stdout
, so redirect it like es6toes5 file.js > output.js
.
Node.js / Using as a library
require("es6-transpiler").run(<Options>)
Options is:
{
filename: string // input file
src: string // input source if not filename
outputToConsole: boolean // if true -> result would be outputted to console
outputFilename: string // if specific -> result would be written to file
}
Other options below in "Options" section.
var es6tr = require("./es6-transpiler");
var result = es6tr.run({filename: "test.js"});
console.log(result.src);
result object is:
{
src: string or "" // on success
errors: array of error messages or [] // on errors
stats: statistics object
ast: transformed ast // ast tree from esprima
getNeedfulList: <function: Array.<string>> // list of necessary polyfills
getNeedfulLib: <function: string> // text of necessary polyfills
getFullLib: <function: string> // text of all available polyfills
}
Options
Example of options
object:
{
//described above:
//"filename" or "scr": "string"
//outputToConsole: false
//outputFilename: true
"environments": ["node", "browser"],
"globals": {
"my": false,
"hat": true
},
"disallowVars": false,
"disallowDuplicated": true,
"disallowUnknownReferences": true,
"includePolyfills": <boolean> | <"full">,
"polyfillsSeparator": <string>
}
globals
lets you list your program's globals, and indicate whether they are
writable (true
) or read-only (false
), just like jshint
.
environments
lets you import a set of pre-defined globals, here node
and
browser
. These default environments are borrowed from jshint
(see
jshint_globals/vars.js).
disallowVars
(defaults to false
) can be enabled to make
usage of var
an error.
disallowDuplicated
(defaults to true
) errors on duplicated
var
definitions in the same function scope.
disallowUnknownReferences
(defaults to true
) errors on references to
unknown global variables.
includePolyfills
(defaults to false
) insert polyfills in the output file.
true
- insert only the necessary polyfills. "full"
- insert all available polyfills.
polyfillsSeparator
(default - empty string) any string that should be inserted before polyfills library.
License
MIT
, see LICENSE file.
Example
See tests
Compatibility
es6-transpiler.js
strives to transpile your program as true to the ES6 semantics as
possible, while being as maximally non-intrusive as possible.
Referenced (inside closure) before declaration
es6-transpiler.js
detects the vast majority of cases where a variable is referenced prior to
its declaration. The one case it cannot detect is the following:
function printx() { console.log(x); }
printx();
let x = 1;
printx();
The first call to printx
is not legal because x
hasn't been initialized at that point
of time, which is impossible to catch reliably with statical analysis.
v8 --harmony
will detect and error on this via run-time checking. es6-transpiler.js
will
happily transpile this example (let
=> var
and that's it), and the transpiled code
will print undefined
on the first call to printx
. This difference should be a very
minor problem in practice.
TODO
- Generators support
- Modules support
- 'pre-es6-node10', 'pre-es6-chrome20' and 'pre-es6-ff24' output modes