Skip to content

Commit

Permalink
Use mutable bindings for default exports (#4182)
Browse files Browse the repository at this point in the history
Escape "default" when used as named export
Create new variable for TDZ default exports
  • Loading branch information
lukastaegert committed Jul 28, 2021
1 parent 824c53f commit 9a23190
Show file tree
Hide file tree
Showing 192 changed files with 326 additions and 247 deletions.
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 };

0 comments on commit 9a23190

Please sign in to comment.