1

Babel is choking on code that uses the module pattern with an arrow function.

If I try to process a file which reads:

const lib = (() => {
  function sum(a, b)  { return a + b; }
  function mult(a, b) { return a * b; }

  return {
    sum,
    mult
  };
}());

Babel gives a SyntaxError

{ SyntaxError: /home/david/Sync/ebs/office/fake.js: Unexpected token, expected "," (9:1)

   7 |     mult
   8 |   };
>  9 | }());
     |  ^
  10 | 
    at Parser.raise (/home/david/Sync/ebs/office/node_modules/@babel/parser/lib/index.js:3939:15)
    at Parser.unexpected (/home/david/Sync/ebs/office/node_modules/@babel/parser/lib/index.js:5248:16)
    at Parser.expect (/home/david/Sync/ebs/office/node_modules/@babel/parser/lib/index.js:5236:28)
    at Parser.parseParenAndDistinguishExpression (/home/david/Sync/ebs/office/node_modules/@babel/parser/lib/index.js:6454:14)
    at Parser.parseExprAtom (/home/david/Sync/ebs/office/node_modules/@babel/parser/lib/index.js:6284:21)
    at Parser.parseExprSubscripts (/home/david/Sync/ebs/office/node_modules/@babel/parser/lib/index.js:5924:21)
    at Parser.parseMaybeUnary (/home/david/Sync/ebs/office/node_modules/@babel/parser/lib/index.js:5903:21)
    at Parser.parseExprOps (/home/david/Sync/ebs/office/node_modules/@babel/parser/lib/index.js:5812:21)
    at Parser.parseMaybeConditional (/home/david/Sync/ebs/office/node_modules/@babel/parser/lib/index.js:5784:21)
    at Parser.parseMaybeAssign (/home/david/Sync/ebs/office/node_modules/@babel/parser/lib/index.js:5731:21)
  pos: 137,
  loc: Position { line: 9, column: 1 },
  code: 'BABEL_PARSE_ERROR' }

However, if I change the code to use an older style function, like

const lib = (function () {
  function sum(a, b)  { return a + b; }
  function mult(a, b) { return a * b; }

  return {
    sum,
    mult
  };
}());

Babel seems to process the file with no issues.

What am I doing wrong? Is there a genuine syntax problem with the arrow function code I am not aware of?

David Y. Stephenson
  • 1,296
  • 4
  • 20
  • 38
  • try -> `})();` instead of `}());` Your generating a function definition, not an expression otherwise. – Keith Oct 31 '18 at 15:42
  • 2
    I just tried copying into the browser console (Chrome), seems like it's a genuine syntax error. It works though if instead of `( () => {...}() )` you do `( () => {...})()`, which is another standard form for immediately-invoked function expressions. – Robin Zigmond Oct 31 '18 at 15:43
  • Why are you not using proper module syntax if you are using ES6? – Bergi Oct 31 '18 at 19:22

2 Answers2

2

Due to the nature of arrow functions and how they are interpreted, (E.g. :

const x = () => ({ objectPropValues });
const x = () => { functionBody };
const x = () => conciseFunctionBody;

I imagine that the second arrow function in

const x = (() => {functionBody})();
const x = (() => {functionBody}());

Can not be allowed, and isn't.

This can probably be confirmed by looking carefully at the ECMA 6 specification for arrow functions.

Cody G
  • 6,752
  • 2
  • 28
  • 40
1

Try moving your paren inside, like this:

})();

const lib = (() => {
  function sum(a, b)  { return a + b; }
  function mult(a, b) { return a * b; }

  return {
    sum,
    mult
  };
})();
console.log(lib)

In ES6, an arrow function basically consists of the following three components:

() => {}

So in order to invoke it immediately it should be wrapped in parentheses and then called, like this:

const lib = (() => {
    //do something
})();
Jonathan Rys
  • 1,564
  • 9
  • 20
  • Why does it need to be different from the older function syntax? – David Y. Stephenson Oct 31 '18 at 16:01
  • @DavidY.Stephenson You'd need to dig into the ES 6 spec to figure that out (unless somebody's willing to do it for you), but basically, it seems that `(() => { }())` is not valid syntax. This isn't a Babel issue. – JLRishe Oct 31 '18 at 16:06
  • There's a more detailed answer here already: https://stackoverflow.com/questions/34589488/es6-immediately-invoked-arrow-function – Jonathan Rys Oct 31 '18 at 20:03