10

I read here that I don't need to put a semicolon after default exports. So this program has an unnecessary semicolon:

export default function() {};

But if my module continues like this:

export default function() {};

(() => {
  // creating a new function scope
})();

then I can't leave the semicolon.

So what is going on here? The grammar says I don't need the semicolon but if I leave it the code means something else?

UPDATE:

If I leave the semicolon:

export default function() {}

(() => {
  // creating a new function scope
})();

then the exported function gets called instead of being exported. babeljs.io compiles the latter into:

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});

exports["default"] = (function () {})(function () {
  // creating a new function scope
})();

;
module.exports = exports["default"];

More precisely after it gets called an error is thrown, because the return value of the first function also gets called (but that is not a function). The error I get in chrome is this:

Uncaught TypeError: (intermediate value)(...) is not a function(…)
Community
  • 1
  • 1
Tamas Hegedus
  • 28,755
  • 12
  • 63
  • 97
  • What makes you not able to leave the semicolon in the second case? Does something give you an error? – loganfsmyth Dec 05 '15 at 22:39
  • @loganfsmyth please see my update – Tamas Hegedus Dec 05 '15 at 22:49
  • possible duplicate of [Default export in ES6. Why don't you need a semicolon?](http://stackoverflow.com/q/33482309/1048572) (if your question wasn't about the babel bug) – Bergi Dec 06 '15 at 13:21
  • 1
    @Bergi `I read here that I don't need to put a semicolon...` I forgot to link the question :( the question you linked inspired my own. At first I suspected inconsistency in the spec itself, then it turned out it is probably a babel bug. – Tamas Hegedus Dec 06 '15 at 13:56

1 Answers1

13

You don't need to add a semicolon after a export default when it's followed by a function declaration, that's what the grammar says.

Babel is wrong, I've filed a bug against it. That code should be interpreted as exporting the function and then running the IIFE as an IIFE.

Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
  • 1
    I'm not entirely sure this is true. in this case, it's still a function declaration, rather than a function expression, so it shouldn't require a semicolon after it. Generally for export syntax, the question of semicolons comes down to whether it would have had a semicolon if you left the `export` part out of the statement. – loganfsmyth Dec 05 '15 at 22:41
  • Hmm http://www.ecma-international.org/ecma-262/6.0/#sec-exports (it's HoistableDeclaration if you were not aware). – Benjamin Gruenbaum Dec 05 '15 at 22:43
  • 1
    @loganfsmyth it's a function declaration that requires semicolons to prevent automatic semicolon insertion. Indeed there was no case of this in ES5 and indeed the semicolon is not a part of the statement and is not really automatically inserted - interesting case indeed. I wonder if the grammar should be amended. I'll raise it in esdiscuss. – Benjamin Gruenbaum Dec 05 '15 at 22:47
  • @loganfsmyth I'm starting to think this is a babel bug. – Benjamin Gruenbaum Dec 05 '15 at 22:54
  • @BenjaminGruenbaum Some versions of WebStorm even raised a warning if I did put a semicolon, telling me I don't even need that. The current one I use (10.0.4) doesn't have that warning – Tamas Hegedus Dec 05 '15 at 22:58
  • @BenjaminGruenbaum So based on the spec, I shouldn't be able to `export default "a string literal"`, as only HoistableDeclaration, ClassDeclaration and AssignmentExpression is allowed? I used `export default {...} // an object literal` everywhere – Tamas Hegedus Dec 05 '15 at 23:09
  • It's fine to `export default` an object literal - it's parsed as an `AssigmentExpression` and not a `HoistableDeclaration`. – Benjamin Gruenbaum Dec 05 '15 at 23:27
  • Yeah you were right, I managed to trace it down: `AssignmentExpression, BitwiseANDExpression, EqualityExpression, RelationalExpression, ShiftExpression, AdditiveExpression, MultiplicativeExpression, UnaryExpression, PostfixExpression, LeftHandSideExpression, NewExpression, MemberExpression, PrimaryExpression, ObjectLiteral` – Tamas Hegedus Dec 06 '15 at 14:14