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

Use mutable bindings for default exports #4182

Merged
merged 1 commit into from Jul 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Chunk.ts
Expand Up @@ -1015,7 +1015,7 @@ export default class Chunk {
}
} else if (variable instanceof SyntheticNamedExportVariable) {
expression = local;
if (format === 'es' && exportName !== 'default') {
if (format === 'es') {
local = variable.renderName!;
}
}
Expand Down
68 changes: 34 additions & 34 deletions src/ast/nodes/Identifier.ts
Expand Up @@ -175,6 +175,40 @@ export default class Identifier extends NodeBase implements PatternNode {
this.getVariableRespectingTDZ().includeCallArguments(context, args);
}

isPossibleTDZ(): boolean {
// return cached value to avoid issues with the next tree-shaking pass
if (this.isTDZAccess !== null) return this.isTDZAccess;

if (
!(this.variable instanceof LocalVariable) ||
!this.variable.kind ||
!(this.variable.kind in tdzVariableKinds)
) {
return (this.isTDZAccess = false);
}

let decl_id;
if (
this.variable.declarations &&
this.variable.declarations.length === 1 &&
(decl_id = this.variable.declarations[0] as any) &&
this.start < decl_id.start &&
closestParentFunctionOrProgram(this) === closestParentFunctionOrProgram(decl_id)
) {
// a variable accessed before its declaration
// in the same function or at top level of module
return (this.isTDZAccess = true);
}

if (!this.variable.initReached) {
// Either a const/let TDZ violation or
// var use before declaration was encountered.
return (this.isTDZAccess = true);
}

return (this.isTDZAccess = false);
}

markDeclarationReached(): void {
this.variable!.initReached = true;
}
Expand Down Expand Up @@ -231,40 +265,6 @@ export default class Identifier extends NodeBase implements PatternNode {
}
return this.variable!;
}

private isPossibleTDZ(): boolean {
// return cached value to avoid issues with the next tree-shaking pass
if (this.isTDZAccess !== null) return this.isTDZAccess;

if (
!(this.variable instanceof LocalVariable) ||
!this.variable.kind ||
!(this.variable.kind in tdzVariableKinds)
) {
return (this.isTDZAccess = false);
}

let decl_id;
if (
this.variable.declarations &&
this.variable.declarations.length === 1 &&
(decl_id = this.variable.declarations[0] as any) &&
this.start < decl_id.start &&
closestParentFunctionOrProgram(this) === closestParentFunctionOrProgram(decl_id)
) {
// a variable accessed before its declaration
// in the same function or at top level of module
return (this.isTDZAccess = true);
}

if (!this.variable.initReached) {
// Either a const/let TDZ violation or
// var use before declaration was encountered.
return (this.isTDZAccess = true);
}

return (this.isTDZAccess = false);
}
}

function closestParentFunctionOrProgram(node: any): any {
Expand Down
1 change: 1 addition & 0 deletions src/ast/variables/ExportDefaultVariable.ts
Expand Up @@ -54,6 +54,7 @@ export default class ExportDefaultVariable extends LocalVariable {
return this.originalId &&
(this.hasId ||
!(
this.originalId.isPossibleTDZ() ||
this.originalId.variable.isReassigned ||
this.originalId.variable instanceof UndefinedVariable ||
// this avoids a circular dependency
Expand Down
18 changes: 7 additions & 11 deletions src/finalisers/es.ts
Expand Up @@ -114,18 +114,14 @@ function getExportBlock(exports: ChunkExports, _: string, varOrConst: string): s
const exportBlock: string[] = [];
const exportDeclaration: string[] = [];
for (const specifier of exports) {
if (specifier.exported === 'default') {
exportBlock.push(`export default ${specifier.local};`);
} else {
if (specifier.expression) {
exportBlock.push(`${varOrConst} ${specifier.local}${_}=${_}${specifier.expression};`);
}
exportDeclaration.push(
specifier.exported === specifier.local
? specifier.local
: `${specifier.local} as ${specifier.exported}`
);
if (specifier.expression) {
exportBlock.push(`${varOrConst} ${specifier.local}${_}=${_}${specifier.expression};`);
}
exportDeclaration.push(
specifier.exported === specifier.local
? specifier.local
: `${specifier.local} as ${specifier.exported}`
);
}
if (exportDeclaration.length) {
exportBlock.push(`export${_}{${_}${exportDeclaration.join(`,${_}`)}${_}};`);
Expand Down
7 changes: 4 additions & 3 deletions src/finalisers/shared/getExportBlock.ts
Expand Up @@ -5,6 +5,7 @@ import {
isDefaultAProperty,
namespaceInteropHelpersByInteropType
} from '../../utils/interopHelpers';
import { RESERVED_NAMES } from '../../utils/reservedNames';

export function getExportBlock(
exports: ChunkExports,
Expand Down Expand Up @@ -65,9 +66,9 @@ export function getExportBlock(
}
}

for (const chunkExport of exports) {
const lhs = `exports.${chunkExport.exported}`;
const rhs = chunkExport.local;
for (const { exported, local } of exports) {
const lhs = `exports${RESERVED_NAMES[exported] ? `['${exported}']` : `.${exported}`}`;
const rhs = local;
if (lhs !== rhs) {
if (exportBlock) exportBlock += n;
exportBlock += `${lhs}${_}=${_}${rhs};`;
Expand Down
Expand Up @@ -11,4 +11,4 @@ class Main1 {
}
}

export default Main1;
export { Main1 as default };
Expand Up @@ -16,4 +16,4 @@ class Main2 {
}
}

export default Main2;
export { Main2 as default };
Expand Up @@ -6,4 +6,4 @@ class Main1 {
}
}

export default Main1;
export { Main1 as default };
Expand Up @@ -6,4 +6,4 @@ class Main2 {
}
}

export default Main2;
export { Main2 as default };
Expand Up @@ -7,4 +7,4 @@ class Main1 {
}
}

export default Main1;
export { Main1 as default };
Expand Up @@ -7,4 +7,4 @@ class Main2 {
}
}

export default Main2;
export { Main2 as default };
Expand Up @@ -5,4 +5,4 @@ var cjs = commonjsGlobal.fn;

var main1 = shared.map(cjs);

export default main1;
export { main1 as default };
Expand Up @@ -2,4 +2,4 @@ import { s as shared } from './generated-shared.js';

var main2 = shared.map(d => d + 2);

export default main2;
export { main2 as default };
Expand Up @@ -5,4 +5,4 @@ import {f as fn$1}from'./generated-dep2.js';function fn () {
fn();
fn$1();
}
}export default Main1;
}export{Main1 as default};
Expand Up @@ -9,4 +9,4 @@ import {f as fn$3}from'./generated-dep2.js';import {fn as fn$2}from'external';fu
fn();
fn$3();
}
}export default Main2;
}export{Main2 as default};
Expand Up @@ -11,4 +11,4 @@ class Main1 {
}
}

export default Main1;
export { Main1 as default };
Expand Up @@ -18,4 +18,4 @@ class Main2 {
}
}

export default Main2;
export { Main2 as default };

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Expand Up @@ -2,4 +2,4 @@ import * as other from './other.js';

var main = other + "extended";

export default main;
export { main as default };
Expand Up @@ -2,4 +2,4 @@ import { d as data } from './generated-shared.js';

var main1 = data.map(d => d + 1);

export default main1;
export { main1 as default };
Expand Up @@ -2,4 +2,4 @@ import { d as data } from './generated-shared.js';

var main2 = data.map(d => d + 2);

export default main2;
export { main2 as default };
@@ -1,3 +1,3 @@
const __icon__ = {};

export default __icon__;
export { __icon__ as default };
Expand Up @@ -2,6 +2,6 @@ define(['require', 'exports'], function (require, exports) { 'use strict';

var solved = 'nested/chunk.js:solved:assets/asset-solved-28a7ac89.txt:../assets/asset-solved-28a7ac89.txt';

exports.default = solved;
exports['default'] = solved;

});
Expand Up @@ -2,4 +2,4 @@

var solved = 'nested/chunk.js:solved:assets/asset-solved-28a7ac89.txt:../assets/asset-solved-28a7ac89.txt';

exports.default = solved;
exports['default'] = solved;
@@ -1,3 +1,3 @@
var solved = 'nested/chunk.js:solved:assets/asset-solved-28a7ac89.txt:../assets/asset-solved-28a7ac89.txt';

export default solved;
export { solved as default };
@@ -1,3 +1,3 @@
var value = 42;

export default value;
export { value as default };
Expand Up @@ -3,7 +3,7 @@ define(['exports'], function (exports) { 'use strict';
const foo = 'bar';
var bar = () => {};

exports.default = bar;
exports['default'] = bar;
exports.foo = foo;

Object.defineProperty(exports, '__esModule', { value: true });
Expand Down
Expand Up @@ -5,5 +5,5 @@ Object.defineProperty(exports, '__esModule', { value: true });
const foo = 'bar';
var bar = () => {};

exports.default = bar;
exports['default'] = bar;
exports.foo = foo;
@@ -1,5 +1,4 @@
const foo = 'bar';
var bar = () => {};

export default bar;
export { foo };
export { bar as default, foo };
Expand Up @@ -13,4 +13,4 @@ class Main {
}
}

export default Main;
export { Main as default };
@@ -1,3 +1,3 @@
var foo = 'default';

export default foo;
export { foo as default };
Expand Up @@ -9,4 +9,4 @@ console.log(external, value);

var commonjs = 42;

export default commonjs;
export { commonjs as default };
@@ -1,3 +1,3 @@
var m2 = {a:1};

export default m2;
export { m2 as default };
@@ -1,3 +1,3 @@
var m3 = {b:2};

export default m3;
export { m3 as default };
@@ -1,3 +1,3 @@
var a = {};

export default a;
export { a as default };
@@ -1,3 +1,3 @@
var foo = 42;

export default foo;
export { foo as default };
@@ -1,3 +1,3 @@
var noExt = 'no-ext';

export default noExt;
export { noExt as default };
@@ -1,3 +1,3 @@
var bar = 'banana';

export default bar;
export { bar as default };
@@ -1,3 +1,3 @@
var baz = 'whatever';

export default baz;
export { baz as default };
@@ -1,3 +1,3 @@
var c = 'One1.js';

export default c;
export { c as default };
@@ -1,3 +1,3 @@
var b = 'One.js';

export default b;
export { b as default };
@@ -1,3 +1,3 @@
var a = 'one.js';

export default a;
export { a as default };
Expand Up @@ -2,7 +2,7 @@ define(['exports'], function (exports) { 'use strict';

var foo = 'default';

exports.default = foo;
exports['default'] = foo;

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

Expand Down
Expand Up @@ -4,4 +4,4 @@ Object.defineProperty(exports, '__esModule', { value: true });

var foo = 'default';

exports.default = foo;
exports['default'] = foo;
@@ -1,3 +1,3 @@
var foo = 'default';

export default foo;
export { foo as default };
@@ -1,3 +1,3 @@
function foo() {}

export default foo;
export { foo as default };