Skip to content

Commit

Permalink
Add option to block-scoping to slow on throw code
Browse files Browse the repository at this point in the history
The let/const plugin can add closures where you don't expect them. This is undesirable in some perf-sensitive projects (ex: React). I added an option that throws whenever the plugin adds a function (as opposed to simply renaming variables when converting to var).
  • Loading branch information
sophiebits committed Jan 30, 2017
1 parent a97be35 commit 53e694c
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 0 deletions.
26 changes: 26 additions & 0 deletions packages/babel-plugin-transform-es2015-block-scoping/README.md
Expand Up @@ -14,12 +14,26 @@ npm install --save-dev babel-plugin-transform-es2015-block-scoping

**.babelrc**

Without options:

```json
{
"plugins": ["transform-es2015-block-scoping"]
}
```

With options:

```json
{
"plugins": [
["transform-es2015-block-scoping", {
"throwIfClosureRequired": true
}]
]
}
```

### Via CLI

```sh
Expand All @@ -33,3 +47,15 @@ require("babel-core").transform("code", {
plugins: ["transform-es2015-block-scoping"]
});
```

## Options `throwIfClosureRequired`

In cases such as the following it's impossible to rewrite let/const without adding an additional function and closure while transforming:

```javascript
for (let i = 0; i < 5; i++) {
setTimeout(() => console.log(i), 1);
}
```

In extremely performance-sensitive code, this can be undesirable. If `"throwIfClosureRequired": true` is set, Babel throws when transforming these patterns instead of automatically adding an additional function.
Expand Up @@ -362,6 +362,12 @@ class BlockScoping {
}

wrapClosure() {
if (this.file.opts.throwIfClosureRequired) {
throw this.blockPath.buildCodeFrameError(
"Compiling let/const in this block would add a closure " +
"(throwIfClosureRequired)."
);
}
const block = this.block;

const outsideRefs = this.outsideLetReferences;
Expand Down
@@ -0,0 +1,6 @@
for (let i = 0; i < 5; i++) {
const l = i;
setTimeout(function() {
console.log(l);
}, 1);
}
@@ -0,0 +1,3 @@
{
"throws": "Compiling let/const in this block would add a closure (throwIfClosureRequired)."
}
@@ -0,0 +1,3 @@
function test() {
let foo = "bar";
}
@@ -0,0 +1,3 @@
function test() {
var foo = "bar";
}
@@ -0,0 +1,3 @@
{
"plugins": [["transform-es2015-block-scoping", { "throwIfClosureRequired": true }], "syntax-jsx", "transform-react-jsx", "transform-es2015-block-scoped-functions", "transform-es2015-arrow-functions"]
}
@@ -0,0 +1,16 @@
function foo() {
switch (2) {
case 0: {
if (true) {
return;
}

const stuff = new Map();
const data = 0;
stuff.forEach(() => {
const d = data;
});
break;
}
}
}
@@ -0,0 +1,3 @@
{
"throws": "Compiling let/const in this block would add a closure (throwIfClosureRequired)."
}

0 comments on commit 53e694c

Please sign in to comment.