Loose mode

Making your code faster (but less spec-compliant)

Loose mode enables certain transformers to generate cleaner output that lacks specific ES6 edgecases. These edgecases are either unlikely to appear in your code or the inclusion of them introduces signifcant overhead.

As a result of loose mode code will execute faster and be much readable and comparable to the original but will deviate from the spec in slight ways.

WARNING

Please be aware of all possible caveats when enabling loose mode.

Usage

require("babel").transform("code", { loose: ["classes", "computedPropertyNames"] });
$ babel --loose classes,computedPropertyNames script.js

All

You can optionally choose to enable fast mode across all transformers instead of manually specifying each one:

require("babel").transform("code", { loose: "all" });
$ babel --loose all script.js

Caveats

classes

Method enumerability

Please note that in loose mode class methods are enumerable. This is not in line with the spec and you may run into issues.

Method assignment

Under loose mode, methods are defined on the class prototype with simple assignments instead of being defined. This can result in the following not working:

class Foo {
  set bar() {
    throw new Error("foo!");
  }
}

class Bar extends Foo {
  bar() {
    // will throw an error when this method is defined
  }
}

When Bar.prototype.foo is defined it triggers the setter on Foo. This is a case that is very unlikely to appear in production code however it's something to keep in mind.

computedPropertyNames

Just like method assignment in classes, in loose mode, computed property names use simple assignments instead of being defined. This is unlikely to be an issue in production code.

forOf

Under loose mode the forOf transformer will output more verbose iteration code.

For example the following:

for (var i of foo) {}

is normally output as:

for (var _iterator = foo[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) {
  var i = _step.value;
}

Under loose mode however it's output as:

for (var _iterator = foo, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
  var i;
  if (_isArray) {
    if (_i >= _iterator.length) break;
    i = _iterator[_i++];
  } else {
    _i = _iterator.next();
    if (_i.done) break;
    i = _i.value;
  }
}

The result is that arrays are put in a fast path, heavily increasing performance. All other iterables will continue to work fine but array iteration will be significantly faster.

modules

As per the spec, import and export are only allowed to be used at the top level. When in loose mode these are allowed to be used anywhere.

templateLiterals

In loose mode, tagged template literal objects aren't frozen.