Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

transform-es2015-modules-commonjs: Invalid handling of default export reassignment #5075

Closed
sebastian-nowak opened this issue Jan 7, 2017 · 4 comments
Labels
i: bug outdated A closed issue/PR that is archived due to age. Recommended to make a new issue

Comments

@sebastian-nowak
Copy link

When exporting a mutable variable as default, it's handled differently depending on how it was exported. See the example below.

exportDefault.js:

let test = 123;
export default test;
test = 256;

exportBraces:js

let test = 123;
export {test as default};
test = 256;

test.js

import {test as test1} from 'exportDefault';
import {test as test2} from 'exportBraces';

console.log(test1); // prints 123
console.log(test2); // prints 256

These two methods should output the same value. You can easily see what's happening if you look at the transpiled code.

exportDefault_transpiled.js:

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
var test = 123;
exports.default = test;

test = 256;

exportBraces_transpiled.js:

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
var test = 123;
exports.default = test;

exports.default = test = 256;

Tested on babel 6.21.0 and on https://babeljs.io/repl/.

@babel-bot
Copy link
Collaborator

Hey @sebastian-nowak! We really appreciate you taking the time to report an issue. The collaborators
on this project attempt to help as many people as possible, but we're a limited number of volunteers,
so it's possible this won't be addressed swiftly.

If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack
community that typically always has someone willing to help. You can sign-up here
for an invite.

@loganfsmyth
Copy link
Member

These two methods should output the same value.

Unfortunately this is a common gotcha. That is not the case. export default EXPRESSION; does not create a live binding.

export default test;

is essentially equivalent to

const _tmp = test;
export {_tmp as default};

meaning that changes to test do not update the exported value.

@sebastian-nowak
Copy link
Author

Oh, I see, thank you for the explanation. These little inconsistencies are really confusing. Surprisingly export default creates a live binding, when exporting a named function or class.

export default function test() {}
test = 123;
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = test;
function test() {}
exports.default = test = 123;

@loganfsmyth
Copy link
Member

Yup. In the grammer here export default HoistableDeclaration and export default ClassDeclaration create live bindings, and export default AssignmentExpression does not.

The important part being here where export default AssignmentExpression is [[LocalName]]: "*default*" whereas the others are [[LocalName]]: localName. *default* is essentially the _tmp from my example.

@lock lock bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label May 5, 2018
@lock lock bot locked as resolved and limited conversation to collaborators May 5, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
i: bug outdated A closed issue/PR that is archived due to age. Recommended to make a new issue
Projects
None yet
Development

No branches or pull requests

4 participants