module exports

David Herman dherman at
Fri Mar 14 12:12:54 PDT 2014

On Mar 14, 2014, at 10:50 AM, Russell Leggett <russell.leggett at> wrote:

> I completely agree with this. It looks like a modifier.

This is a good point, and folks working on the Square transpiler noticed this, too. I think there's a more surgical fix, though (and I'm not entertaining major syntax redesign at this point). In fact it's one with precedent in JS. In statements, we allow both expressions and declarations, which is a syntactic overlap. But visually people expect something that looks like a declaration in that context to be a declaration, so the lookahead restriction breaks the tie in favor of declarations.

I think we're seeing the exact same phenomenon with `export default` -- the modifiers make it look more like a declaration context. So I think we should consider doing the same thing as we do for ExpressionStatement:

    ExportDeclaration :
        export default FunctionDeclaration ;
        export default ClassDeclaration ;
        export default [lookahead !in { function, class }] AssignmentExpression ;

This actually results in no net change to the language syntax, but it allows us to change the scoping rules so that function and class declarations scope to the entire module:

    // function example
    export default function foo() { ... }

    // class example
    export default class Foo { ... }
    let x = new Foo(...);

    // expression example
    export default { x: 1, y: 2, z: 3 };

I argue that not only does this avoid violating surprise, it's not any more of a special-casing logic than we already have with ExpressionStatement, because it's the same phenomenon: a context that allows a formally ambiguous union of two productions, but whose context strongly suggests the declaration interpretation over the expression interpretation in the overlapping cases.


More information about the es-discuss mailing list