Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

lebab

lebab5.3kMIT3.2.7TypeScript support: included

Turn your ES5 code into readable ES6/ES7

es5, es6, es2015, es7, es2016, transpiler, transpile

readme

Build Status Coverage Status Dependencies License Version

Lebab

Lebab

Lebab transpiles your ES5 code to ES6/ES7. It does exactly the opposite of what Babel does. If you want to understand what Lebab exactly does, try the live demo.

Install

Install it using npm:

$ npm install -g lebab

Usage

Convert your old-fashioned code using the lebab cli tool, enabling a specific transformation:

$ lebab es5.js -o es6.js --transform let

Or transform an entire directory of files in-place:

# .js files only
$ lebab --replace src/js/ --transform arrow
# For other file extensions, use explicit globbing
$ lebab --replace 'src/js/**/*.jsx' --transform arrow

For all the possible values for --transform option see the detailed docs below or use --help from command line.

Features and known limitations

The recommended way of using Lebab is to apply one transform at a time, read what exactly the transform does and what are its limitations, apply it for your code and inspect the diff carefully.

Safe transforms

These transforms can be applied with relatively high confidence. They use pretty straight-forward and strict rules for changing the code. The resulting code should be almost 100% equivalent of the original code.

  • <input checked="" disabled="" type="checkbox"> arrow - callbacks to arrow functions
    • <input checked="" disabled="" type="checkbox"> Converts bound functions like function(){}.bind(this)
    • <input checked="" disabled="" type="checkbox"> not applied to unbound functions that use this
    • <input checked="" disabled="" type="checkbox"> not applied to functions that use arguments
    • <input checked="" disabled="" type="checkbox"> not applied to object properties (use obj-method transform)
    • <input disabled="" type="checkbox"> does not remove that = this assignments
    • <input disabled="" type="checkbox"> LIMITATION: can mess up prototype-based classes, run the class transform first to prevent this.
  • <input checked="" disabled="" type="checkbox"> arrow-return - drop return statements in arrow functions
    • <input checked="" disabled="" type="checkbox"> converts immediate return { return x; } to => x
    • <input checked="" disabled="" type="checkbox"> applies to arrow functions and nested arrow functions
    • <input disabled="" type="checkbox"> LIMITATION only applies to arrow functions (run the arrow transform first)
  • <input checked="" disabled="" type="checkbox"> for-of - for loop to for-of loop
    • <input checked="" disabled="" type="checkbox"> uses name item for loop variable when loop body begins with var item = array[i];
    • <input disabled="" type="checkbox"> does not work when no such alias defined at the start of loop body
    • <input disabled="" type="checkbox"> LIMITATION requires let/const variables (run the let transform first)
  • <input checked="" disabled="" type="checkbox"> for-each - for loop to Array.forEach()
    • <input checked="" disabled="" type="checkbox"> uses name item for forEach parameter when loop body begins with var item = array[i];
    • <input disabled="" type="checkbox"> does not work when no such alias defined at the start of loop body
    • <input checked="" disabled="" type="checkbox"> adds index parameter when loop body makes use of the index variable.
    • <input disabled="" type="checkbox"> LIMITATION requires let/const variables (run the let transform first)
  • <input checked="" disabled="" type="checkbox"> arg-rest - use of arguments to function(...args)
  • <input checked="" disabled="" type="checkbox"> arg-spread - use of apply() to spread operator
    • <input checked="" disabled="" type="checkbox"> recognizes obj.method.apply(obj, args)
    • <input checked="" disabled="" type="checkbox"> recognizes func.apply(undefined, args)
  • <input checked="" disabled="" type="checkbox"> obj-method - function values in object to methods
  • <input checked="" disabled="" type="checkbox"> obj-shorthand - {foo: foo} to {foo}
    • <input checked="" disabled="" type="checkbox"> ignores numeric and NaN properties
    • <input disabled="" type="checkbox"> does not convert string properties
  • <input checked="" disabled="" type="checkbox"> no-strict - removal of "use strict" directives
    • <input checked="" disabled="" type="checkbox"> does not touch stuff like x = "use strict";
  • <input checked="" disabled="" type="checkbox"> exponent - Math.pow() to ** operator (ES7)
    • <input checked="" disabled="" type="checkbox"> Full support for all new syntax from ES7
  • <input checked="" disabled="" type="checkbox"> multi-var - single var x,y; declaration to multiple var x; var y; (refactor)

Unsafe transforms

These transforms should be applied with caution. They either use heuristics which can't guarantee that the resulting code is equivalent of the original code, or they have significant bugs which can result in breaking your code.

  • <input checked="" disabled="" type="checkbox"> let - var to let/const
    • <input checked="" disabled="" type="checkbox"> never modified variables are converted to const
    • <input checked="" disabled="" type="checkbox"> properly recognizes block-scoping
    • <input checked="" disabled="" type="checkbox"> splits single var declaration to multiple let/const declarations if needed
    • <input checked="" disabled="" type="checkbox"> recognizes vars defined/assigned using destructuring
    • <input checked="" disabled="" type="checkbox"> vars that conflict with block-scoping are not converted
    • <input checked="" disabled="" type="checkbox"> repeated declarations of the same var are not converted
    • <input checked="" disabled="" type="checkbox"> existing let/const are not converted
    • <input disabled="" type="checkbox"> BUG fails with repeated variable definitions that use destructuring
    • <input disabled="" type="checkbox"> BUG fails with closure over a loop variable
    • <input disabled="" type="checkbox"> BUG fails when function closes over variable declared after function is called
  • <input checked="" disabled="" type="checkbox"> class - function/prototypes to classes
    • <input checked="" disabled="" type="checkbox"> recognizes Foo.prototype.method = function(){ ... };
    • <input checked="" disabled="" type="checkbox"> recognizes Foo.prototype = { ...methods... };
    • <input checked="" disabled="" type="checkbox"> recognizes static methods like Foo.method = function(){ ... };
    • <input checked="" disabled="" type="checkbox"> recognizes getters/setters defined with Object.defineProperty()
    • <input checked="" disabled="" type="checkbox"> recognizes getters/setters defined with Object.defineProperties()
    • <input checked="" disabled="" type="checkbox"> recognizes inheritance with Child.prototype = new Parent()
    • <input checked="" disabled="" type="checkbox"> recognizes inheritance with util.inherits(Child, Parent);
    • <input checked="" disabled="" type="checkbox"> converts superclass constructor calls to super()
    • <input checked="" disabled="" type="checkbox"> converts superclass method calls to super.method()
    • <input disabled="" type="checkbox"> LIMITATION does not require super() call in subclass constructor
    • <input disabled="" type="checkbox"> LIMITATION does not enforce super() call position in subclass constructor
    • <input disabled="" type="checkbox"> LIMITATION does not support namespaced classes
  • <input checked="" disabled="" type="checkbox"> commonjs - CommonJS module definition to ES6 modules
    • <input checked="" disabled="" type="checkbox"> converts var foo = require("foo") to import foo from "foo"
    • <input checked="" disabled="" type="checkbox"> converts var bar = require("foo").bar to import {bar} from "foo"
    • <input checked="" disabled="" type="checkbox"> converts var {bar} = require("foo") to import {bar} from "foo"
    • <input checked="" disabled="" type="checkbox"> converts module.exports = <anything> to export default <anything>
    • <input checked="" disabled="" type="checkbox"> converts exports.foo = function(){} to export function foo(){}
    • <input checked="" disabled="" type="checkbox"> converts exports.Foo = class {} to export class Foo {}
    • <input checked="" disabled="" type="checkbox"> converts exports.foo = 123 to export var foo = 123
    • <input checked="" disabled="" type="checkbox"> converts exports.foo = bar to export {bar as foo}
    • <input disabled="" type="checkbox"> LIMITATION does not check if named export conflicts with existing variable names
    • <input disabled="" type="checkbox"> LIMITATION Ignores imports/exports inside nested blocks/functions
    • <input disabled="" type="checkbox"> LIMITATION only handles require() calls in var declarations
    • <input disabled="" type="checkbox"> LIMITATION does not ensure that imported variable is treated as const
    • <input disabled="" type="checkbox"> LIMITATION does not ensure named exports are imported with correct ES6 syntax
  • <input checked="" disabled="" type="checkbox"> template - string concatenation to template strings
  • <input checked="" disabled="" type="checkbox"> default-param - default parameters instead of a = a || 2
    • <input checked="" disabled="" type="checkbox"> recognizes a = a || 2
    • <input checked="" disabled="" type="checkbox"> recognizes a = a ? a : 2
    • <input checked="" disabled="" type="checkbox"> recognizes a = a === undefined ? 2 : a
    • <input checked="" disabled="" type="checkbox"> recognizes a = typeof a === 'undefined' ? 2 : a
    • <input disabled="" type="checkbox"> LIMITATION transforming a = a || 2 does not produce strictly equivalent code
  • <input checked="" disabled="" type="checkbox"> destruct-param - use destructuring for objects in function parameters
    • <input checked="" disabled="" type="checkbox"> converts (obj) => obj.a + obj.b to ({a, b}) => a + b
    • <input checked="" disabled="" type="checkbox"> does not transform when conflicts with existing variables
    • <input checked="" disabled="" type="checkbox"> does not transform when object properties are modified
    • <input disabled="" type="checkbox"> LIMITATION Only objects with maximum of 4 properties are transformed
    • <input disabled="" type="checkbox"> BUG Can conflict with variables introduced by the transform itself
  • <input checked="" disabled="" type="checkbox"> includes - array.indexOf(foo) !== -1 to array.includes(foo) (ES7)
    • <input checked="" disabled="" type="checkbox"> works for both strings and arrays
    • <input checked="" disabled="" type="checkbox"> converts !== -1 to array.includes(foo)
    • <input checked="" disabled="" type="checkbox"> converts === -1 to !array.includes(foo)
    • <input checked="" disabled="" type="checkbox"> recognizes all kinds of comparisons >= 0, > -1, etc
    • <input checked="" disabled="" type="checkbox"> recognizes both indexOf() != -1 and -1 != indexOf()
    • <input disabled="" type="checkbox"> LIMITATION does not detect that indexOf() is called on an actual Array or String.

Programming API

Simply import and call the transform() function:

import {transform} from 'lebab';
const {code, warnings} = transform(
  'var f = function(a) { return a; };', // code to transform
  ['let', 'arrow', 'arrow-return'] // transforms to apply
);
console.log(code); // -> "const f = a => a;"

The warnings will be an array of objects like:

[
  {line: 12, msg: 'Unable to transform var', type: 'let'},
  {line: 45, msg: 'Can not use arguments in arrow function', type: 'arrow'},
]

Most of the time there won't be any warnings and the array will be empty.

Editor plugins

Alternatively one can use Lebab through plugins in the following editors:

What's next?

Which feature should Lebab implement next? Let us know by creating an issue or voicing your opinion in existing one.

Want to contribute? Read how Lebab looks for patterns in syntax trees.