Skip to content

Commit b01f4be

Browse files
committed
fix(bug): fixes issue with default exports of varying types
1 parent f75e6ba commit b01f4be

14 files changed

+95
-23
lines changed

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@
5151
"@wessberg/scaffold": "^1.0.17",
5252
"@wessberg/ts-config": "^0.0.39",
5353
"standard-changelog": "^2.0.7",
54-
"@wessberg/rollup-plugin-ts": "^1.1.45",
55-
"tslint": "^5.15.0",
56-
"prettier": "^1.16.4",
54+
"@wessberg/rollup-plugin-ts": "^1.1.46",
55+
"tslint": "^5.16.0",
56+
"prettier": "^1.17.0",
5757
"pretty-quick": "^1.10.0",
5858
"husky": "^1.3.1",
5959
"np": "^4.0.2"
@@ -73,9 +73,9 @@
7373
"@types/mkdirp": "^0.5.2",
7474
"@types/node": "^11.13.4",
7575
"@types/resolve": "0.0.8",
76-
"@wessberg/browserslist-generator": "1.0.16",
76+
"@wessberg/browserslist-generator": "1.0.18",
7777
"@wessberg/stringutil": "^1.0.18",
78-
"browserslist": "^4.5.4",
78+
"browserslist": "^4.5.5",
7979
"find-up": "^3.0.0",
8080
"magic-string": "^0.25.2",
8181
"mkdirp": "^0.5.1",
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import {OutputChunk} from "rollup";
2+
import {SyntaxKind, TypeChecker} from "typescript";
23

34
export interface IDeclarationBundlerOptions {
45
chunk: OutputChunk;
56
usedExports: Set<string>;
7+
typeChecker: TypeChecker;
68
supportedExtensions: string[];
79
localModuleNames: string[];
810
moduleNames: string[];
911
relativeOutFileName: string;
1012
absoluteOutFileName: string;
1113
entryFileNames: string[];
1214
chunkToOriginalFileMap: Map<string, string[]>;
13-
identifiersForDefaultExportsForModules: Map<string, string>;
15+
identifiersForDefaultExportsForModules: Map<string, [string, SyntaxKind]>;
1416
}

src/service/transformer/declaration-bundler/update-exports/visitor/visit-class-declaration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export function visitClassDeclaration({
2929

3030
// If the node has a default export, mark it as the identifier for the default export of that module
3131
if (hasDefaultExportModifier(node.modifiers)) {
32-
identifiersForDefaultExportsForModules.set(sourceFile.fileName, node.name!.text);
32+
identifiersForDefaultExportsForModules.set(sourceFile.fileName, [node.name!.text, node.kind]);
3333
} else {
3434
// Add the node name to the exported symbols
3535
parsedExportedSymbols.add(node.name!.text);

src/service/transformer/declaration-bundler/update-exports/visitor/visit-enum-declaration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export function visitEnumDeclaration({
2929

3030
// If the node has a default export, mark it as the identifier for the default export of that module
3131
if (hasDefaultExportModifier(node.modifiers)) {
32-
identifiersForDefaultExportsForModules.set(sourceFile.fileName, node.name.text);
32+
identifiersForDefaultExportsForModules.set(sourceFile.fileName, [node.name.text, node.kind]);
3333
} else {
3434
// Add the node name to the exported symbols
3535
parsedExportedSymbols.add(node.name.text);

src/service/transformer/declaration-bundler/update-exports/visitor/visit-export-assignment.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,26 @@
1-
import {ExportAssignment, VariableStatement} from "typescript";
1+
import {ExportAssignment, isIdentifier, VariableStatement} from "typescript";
22
import {UpdateExportsVisitorOptions} from "../update-exports-visitor-options";
3+
import {getAliasedDeclaration} from "../../util/symbol/get-aliased-declaration";
34

45
/**
56
* Visits the given ExportAssignment.
67
* @param {UpdateExportsVisitorOptions<ExportAssignment>} options
78
* @returns {ExportAssignment | VariableStatement | undefined}
89
*/
9-
export function visitExportAssignment({node, isEntry}: UpdateExportsVisitorOptions<ExportAssignment>): ExportAssignment | VariableStatement | undefined {
10+
export function visitExportAssignment({
11+
node,
12+
sourceFile,
13+
isEntry,
14+
typeChecker,
15+
identifiersForDefaultExportsForModules
16+
}: UpdateExportsVisitorOptions<ExportAssignment>): ExportAssignment | VariableStatement | undefined {
1017
// Only preserve the node if it is part of the entry file for the chunk
1118
if (isEntry) {
1219
return node;
20+
} else if (isIdentifier(node.expression)) {
21+
const declaration = getAliasedDeclaration(node.expression, typeChecker);
22+
const kind = declaration == null ? node.expression.kind : declaration.kind;
23+
identifiersForDefaultExportsForModules.set(sourceFile.fileName, [node.expression.text, kind]);
1324
}
1425

1526
return undefined;

src/service/transformer/declaration-bundler/update-exports/visitor/visit-export-declaration.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export function visitExportDeclaration({
3737
const specifier = node.moduleSpecifier;
3838
const symbol = (node as {symbol?: Symbol}).symbol;
3939
const isExportStar = symbol != null && (symbol.flags & SymbolFlags.ExportStar) !== 0;
40+
4041
if (specifier == null || !isStringLiteralLike(specifier)) {
4142
// Remove the export if it exports no bindings at all
4243
if (node.moduleSpecifier == null && node.exportClause != null && node.exportClause.elements.length < 1) return undefined;
@@ -85,9 +86,9 @@ export function visitExportDeclaration({
8586
if (identifiersForDefaultExportsForModules.has(path)) {
8687
// We have a match!
8788
if (element.propertyName != null) {
88-
exportSpecifiersWithReplacements.set(element, createExportSpecifier(identifiersForDefaultExportsForModules.get(path)!, element.name));
89+
exportSpecifiersWithReplacements.set(element, createExportSpecifier(identifiersForDefaultExportsForModules.get(path)![0], element.name));
8990
} else {
90-
exportSpecifiersWithReplacements.set(element, createExportSpecifier(identifiersForDefaultExportsForModules.get(path)!, "default"));
91+
exportSpecifiersWithReplacements.set(element, createExportSpecifier(identifiersForDefaultExportsForModules.get(path)![0], "default"));
9192
}
9293
break;
9394
}

src/service/transformer/declaration-bundler/update-exports/visitor/visit-function-declaration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export function visitFunctionDeclaration({
2929

3030
// If the Function has a default export, mark it as the identifier for the default export of that module
3131
if (hasDefaultExportModifier(node.modifiers)) {
32-
identifiersForDefaultExportsForModules.set(sourceFile.fileName, node.name!.text);
32+
identifiersForDefaultExportsForModules.set(sourceFile.fileName, [node.name!.text, node.kind]);
3333
} else {
3434
// Add the function name to the exported symbols
3535
parsedExportedSymbols.add(node.name!.text);

src/service/transformer/declaration-bundler/update-exports/visitor/visit-import-declaration.ts

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@ import {
22
createIdentifier,
33
createModifier,
44
createStringLiteral,
5+
createTypeAliasDeclaration,
6+
createTypeQueryNode,
7+
createTypeReferenceNode,
58
createVariableDeclaration,
69
createVariableDeclarationList,
710
createVariableStatement,
811
ImportDeclaration,
912
isStringLiteralLike,
1013
NodeFlags,
1114
SyntaxKind,
15+
TypeAliasDeclaration,
1216
updateImportDeclaration,
1317
VariableStatement
1418
} from "typescript";
@@ -20,7 +24,7 @@ import {setExtension} from "../../../../../util/path/path-util";
2024
/**
2125
* Visits the given ImportDeclaration.
2226
* @param {UpdateExportsVisitorOptions<ImportDeclaration>} options
23-
* @returns {VariableStatement | undefined}
27+
* @returns {ImportDeclaration | VariableStatement | TypeAliasDeclaration | undefined}
2428
*/
2529
export function visitImportDeclaration({
2630
node,
@@ -30,7 +34,7 @@ export function visitImportDeclaration({
3034
relativeOutFileName,
3135
chunkToOriginalFileMap,
3236
identifiersForDefaultExportsForModules
33-
}: UpdateExportsVisitorOptions<ImportDeclaration>): ImportDeclaration | VariableStatement | undefined {
37+
}: UpdateExportsVisitorOptions<ImportDeclaration>): ImportDeclaration | VariableStatement | TypeAliasDeclaration | undefined {
3438
const specifier = node.moduleSpecifier;
3539
if (specifier == null || !isStringLiteralLike(specifier)) return node;
3640

@@ -51,10 +55,36 @@ export function visitImportDeclaration({
5155
for (const extension of ["", ...supportedExtensions]) {
5256
const path = extension === "" ? join(dirname(sourceFile.fileName), specifier.text) : setExtension(join(dirname(sourceFile.fileName), specifier.text), extension);
5357
if (identifiersForDefaultExportsForModules.has(path)) {
54-
return createVariableStatement(
55-
[createModifier(SyntaxKind.DeclareKeyword)],
56-
createVariableDeclarationList([createVariableDeclaration(node.importClause.name.text, undefined, createIdentifier(identifiersForDefaultExportsForModules.get(path)!))], NodeFlags.Const)
57-
);
58+
const [identifier, kind] = identifiersForDefaultExportsForModules.get(path)!;
59+
60+
// If the name of the identifier is identical to that of the import, it is already in the scope with the correct name. Leave it be
61+
if (identifier === node.importClause.name.text) continue;
62+
63+
switch (kind) {
64+
case SyntaxKind.ClassDeclaration:
65+
case SyntaxKind.ClassExpression: {
66+
return createVariableStatement(
67+
[createModifier(SyntaxKind.DeclareKeyword)],
68+
createVariableDeclarationList([createVariableDeclaration(node.importClause.name.text, createTypeQueryNode(createIdentifier(identifier)))], NodeFlags.Const)
69+
);
70+
}
71+
72+
case SyntaxKind.TypeAliasDeclaration:
73+
case SyntaxKind.InterfaceDeclaration:
74+
case SyntaxKind.EnumDeclaration: {
75+
return createTypeAliasDeclaration(undefined, [createModifier(SyntaxKind.DeclareKeyword)], node.importClause.name.text, undefined, createTypeReferenceNode(identifier, undefined));
76+
}
77+
78+
case SyntaxKind.FunctionDeclaration:
79+
case SyntaxKind.FunctionExpression:
80+
case SyntaxKind.VariableDeclaration:
81+
default: {
82+
return createVariableStatement(
83+
[createModifier(SyntaxKind.DeclareKeyword)],
84+
createVariableDeclarationList([createVariableDeclaration(node.importClause.name.text, undefined, createIdentifier(identifier))], NodeFlags.Const)
85+
);
86+
}
87+
}
5888
}
5989
}
6090
}

src/service/transformer/declaration-bundler/update-exports/visitor/visit-interface-declaration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export function visitInterfaceDeclaration({
2929

3030
// If the node has a default export, mark it as the identifier for the default export of that module
3131
if (hasDefaultExportModifier(node.modifiers)) {
32-
identifiersForDefaultExportsForModules.set(sourceFile.fileName, node.name.text);
32+
identifiersForDefaultExportsForModules.set(sourceFile.fileName, [node.name.text, node.kind]);
3333
} else {
3434
// Add the node name to the exported symbols
3535
parsedExportedSymbols.add(node.name.text);

src/service/transformer/declaration-bundler/update-exports/visitor/visit-module-declaration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export function visitModuleDeclaration({
2929

3030
// If the node has a default export, mark it as the identifier for the default export of that module
3131
if (hasDefaultExportModifier(node.modifiers)) {
32-
identifiersForDefaultExportsForModules.set(sourceFile.fileName, node.name.text);
32+
identifiersForDefaultExportsForModules.set(sourceFile.fileName, [node.name.text, node.kind]);
3333
} else {
3434
// Add the node name to the exported symbols
3535
parsedExportedSymbols.add(node.name.text);

0 commit comments

Comments
 (0)