Skip to content

Commit e4f4d6a

Browse files
authored
Fix and improve default export alias logic (#3521)
* Create failing test * Improve default export short-cut handling * Improve names * Improve coverage
1 parent 8db16bd commit e4f4d6a

114 files changed

Lines changed: 370 additions & 252 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/Chunk.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -769,15 +769,13 @@ export default class Chunk {
769769
for (const dep of this.dependencies) {
770770
const imports: ImportSpecifier[] = [];
771771
for (const variable of this.imports) {
772-
const renderedVariable =
773-
variable instanceof ExportDefaultVariable ? variable.getOriginalVariable() : variable;
774772
if (
775773
(variable.module instanceof Module
776774
? variable.module.chunk === dep
777775
: variable.module === dep) &&
778-
!renderedImports.has(renderedVariable)
776+
!renderedImports.has(variable)
779777
) {
780-
renderedImports.add(renderedVariable);
778+
renderedImports.add(variable);
781779
imports.push({
782780
imported:
783781
variable.module instanceof ExternalModule
@@ -1007,10 +1005,12 @@ export default class Chunk {
10071005

10081006
private setUpChunkImportsAndExportsForModule(module: Module) {
10091007
for (let variable of module.imports) {
1008+
if (variable instanceof SyntheticNamedExportVariable) {
1009+
variable = variable.getBaseVariable();
1010+
} else if (variable instanceof ExportDefaultVariable) {
1011+
variable = variable.getOriginalVariable();
1012+
}
10101013
if ((variable.module as Module).chunk !== this) {
1011-
if (variable instanceof SyntheticNamedExportVariable) {
1012-
variable = variable.getOriginalVariable();
1013-
}
10141014
this.imports.add(variable);
10151015
if (
10161016
!(variable instanceof NamespaceVariable && this.graph.preserveModules) &&
@@ -1029,7 +1029,7 @@ export default class Chunk {
10291029
this.exports.add(exportedVariable);
10301030
const isSynthetic = exportedVariable instanceof SyntheticNamedExportVariable;
10311031
const importedVariable = isSynthetic
1032-
? (exportedVariable as SyntheticNamedExportVariable).getOriginalVariable()
1032+
? (exportedVariable as SyntheticNamedExportVariable).getBaseVariable()
10331033
: exportedVariable;
10341034
const exportingModule = importedVariable.module;
10351035
if (

src/Module.ts

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ export default class Module {
232232
private astContext!: AstContext;
233233
private context: string;
234234
private customTransformCache!: boolean;
235-
private defaultExport: ExportDefaultVariable | null | undefined = null;
235+
private defaultExport: Variable | null | undefined = null;
236236
private esTreeAst!: acorn.Node;
237237
private exportAllModules: (Module | ExternalModule)[] = [];
238238
private exportNamesByVariable: Map<Variable, string[]> | null = null;
@@ -324,7 +324,7 @@ export default class Module {
324324
getDefaultExport() {
325325
if (this.defaultExport === null) {
326326
this.defaultExport = undefined;
327-
this.defaultExport = this.getVariableForExportName('default') as ExportDefaultVariable;
327+
this.defaultExport = this.getVariableForExportName('default');
328328
}
329329
if (!this.defaultExport) {
330330
return error({
@@ -339,21 +339,23 @@ export default class Module {
339339
getDependenciesToBeIncluded(): Set<Module | ExternalModule> {
340340
if (this.relevantDependencies) return this.relevantDependencies;
341341
const relevantDependencies = new Set<Module | ExternalModule>();
342-
for (const variable of this.imports) {
343-
relevantDependencies.add(
344-
variable instanceof SyntheticNamedExportVariable
345-
? variable.getOriginalVariable().module!
346-
: variable.module!
347-
);
342+
for (let variable of this.imports) {
343+
if (variable instanceof SyntheticNamedExportVariable) {
344+
variable = variable.getBaseVariable();
345+
} else if (variable instanceof ExportDefaultVariable) {
346+
variable = variable.getOriginalVariable();
347+
}
348+
relevantDependencies.add(variable.module!);
348349
}
349350
if (this.isEntryPoint || this.dynamicallyImportedBy.length > 0 || this.graph.preserveModules) {
350351
for (const exportName of [...this.getReexports(), ...this.getExports()]) {
351-
const variable = this.getVariableForExportName(exportName);
352-
relevantDependencies.add(
353-
variable instanceof SyntheticNamedExportVariable
354-
? variable.getOriginalVariable().module!
355-
: variable.module!
356-
);
352+
let variable = this.getVariableForExportName(exportName);
353+
if (variable instanceof SyntheticNamedExportVariable) {
354+
variable = variable.getBaseVariable();
355+
} else if (variable instanceof ExportDefaultVariable) {
356+
variable = variable.getOriginalVariable();
357+
}
358+
relevantDependencies.add(variable.module!);
357359
}
358360
}
359361
if (this.graph.treeshakingOptions) {
@@ -402,7 +404,10 @@ export default class Module {
402404
}
403405
const exportNamesByVariable: Map<Variable, string[]> = new Map();
404406
for (const exportName of this.getAllExportNames()) {
405-
const tracedVariable = this.getVariableForExportName(exportName);
407+
let tracedVariable = this.getVariableForExportName(exportName);
408+
if (tracedVariable instanceof ExportDefaultVariable) {
409+
tracedVariable = tracedVariable.getOriginalVariable();
410+
}
406411
if (
407412
!tracedVariable ||
408413
!(tracedVariable.included || tracedVariable instanceof ExternalVariable)

src/ast/nodes/ExportDefaultDeclaration.ts

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ import { ExpressionNode, IncludeChildren, NodeBase } from './shared/Node';
1717
const WHITESPACE = /\s/;
1818

1919
// The header ends at the first non-white-space after "default"
20-
function getDeclarationStart(code: string, start = 0) {
20+
function getDeclarationStart(code: string, start: number) {
2121
start = findFirstOccurrenceOutsideComment(code, 'default', start) + 7;
2222
while (WHITESPACE.test(code[start])) start++;
2323
return start;
2424
}
2525

26-
function getIdInsertPosition(code: string, declarationKeyword: string, start = 0) {
26+
function getIdInsertPosition(code: string, declarationKeyword: string, start: number) {
2727
const declarationEnd =
2828
findFirstOccurrenceOutsideComment(code, declarationKeyword, start) + declarationKeyword.length;
2929
code = code.slice(declarationEnd, findFirstOccurrenceOutsideComment(code, '{', declarationEnd));
@@ -84,15 +84,7 @@ export default class ExportDefaultDeclaration extends NodeBase {
8484
);
8585
} else if (this.variable.getOriginalVariable() !== this.variable) {
8686
// Remove altogether to prevent re-declaring the same variable
87-
if (options.format === 'system' && this.variable.exportName) {
88-
code.overwrite(
89-
start,
90-
end,
91-
`exports('${this.variable.exportName}', ${this.variable.getName()});`
92-
);
93-
} else {
94-
treeshakeNode(this, code, start, end);
95-
}
87+
treeshakeNode(this, code, start, end);
9688
return;
9789
} else if (this.variable.included) {
9890
this.renderVariableDeclaration(code, declarationStart, options);

src/ast/variables/ExportDefaultVariable.ts

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -73,22 +73,4 @@ export default class ExportDefaultVariable extends LocalVariable {
7373
}
7474
return this.originalVariable;
7575
}
76-
77-
setRenderNames(baseName: string | null, name: string | null) {
78-
const original = this.getOriginalVariable();
79-
if (original === this) {
80-
super.setRenderNames(baseName, name);
81-
} else {
82-
original.setRenderNames(baseName, name);
83-
}
84-
}
85-
86-
setSafeName(name: string | null) {
87-
const original = this.getOriginalVariable();
88-
if (original === this) {
89-
super.setSafeName(name);
90-
} else {
91-
original.setSafeName(name);
92-
}
93-
}
9476
}

src/ast/variables/SyntheticNamedExportVariable.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,30 @@
11
import Module, { AstContext } from '../../Module';
2-
import ExportDefaultVariable from './ExportDefaultVariable';
32
import Variable from './Variable';
43

54
export default class SyntheticNamedExportVariable extends Variable {
65
context: AstContext;
7-
defaultVariable: ExportDefaultVariable;
6+
defaultVariable: Variable;
87
module: Module;
98

10-
constructor(context: AstContext, name: string, defaultVariable: ExportDefaultVariable) {
9+
constructor(context: AstContext, name: string, defaultVariable: Variable) {
1110
super(name);
1211
this.context = context;
1312
this.module = context.module;
1413
this.defaultVariable = defaultVariable;
1514
}
1615

16+
getBaseVariable(): Variable {
17+
return this.defaultVariable instanceof SyntheticNamedExportVariable
18+
? this.defaultVariable.getBaseVariable()
19+
: this.defaultVariable;
20+
}
21+
1722
getName(): string {
1823
const name = this.name;
1924
const renderBaseName = this.defaultVariable.getName();
2025
return `${renderBaseName}${getPropertyAccess(name)}`;
2126
}
2227

23-
getOriginalVariable(): Variable {
24-
return this.defaultVariable.getOriginalVariable();
25-
}
26-
2728
include() {
2829
if (!this.included) {
2930
this.included = true;

test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/system/generated-dep1.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ System.register([], function (exports) {
33
return {
44
execute: function () {
55

6-
var x = 42;
7-
exports('x', x);console.log('dep1');
6+
var x = exports('x', 42);
7+
console.log('dep1');
88

99
}
1010
};

test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/system/generated-dep2.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ System.register([], function (exports) {
33
return {
44
execute: function () {
55

6-
var x = 43;
7-
exports('x', x);console.log('dep2');
6+
var x = exports('x', 43);
7+
console.log('dep2');
88

99
}
1010
};

test/chunking-form/samples/chunk-namespace-boundary/_expected/amd/generated-shared.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ define(['exports'], function (exports) { 'use strict';
66
var shared = commonjsGlobal.data;
77

88
exports.commonjsGlobal = commonjsGlobal;
9-
exports.d = shared;
9+
exports.shared = shared;
1010

1111
});

test/chunking-form/samples/chunk-namespace-boundary/_expected/amd/main1.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ define(['./generated-shared'], function (shared) { 'use strict';
33
shared.commonjsGlobal.fn = d => d + 1;
44
var cjs = shared.commonjsGlobal.fn;
55

6-
var main1 = shared.d.map(cjs);
6+
var main1 = shared.shared.map(cjs);
77

88
return main1;
99

test/chunking-form/samples/chunk-namespace-boundary/_expected/amd/main2.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
define(['./generated-shared'], function (shared) { 'use strict';
22

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

55
return main2;
66

0 commit comments

Comments
 (0)