Skip to content

Commit e379aeb

Browse files
authored
Fix alias of module.exports->exports->IIFE (#27992)
In JS, when you assign `module.exports = exports` and the entire module is wrapped in an IIFE, the resulting `export=` symbol, after following aliases, is the module itself. This results in trying to merge the file's exports with itself inside `getCommonJsExportEquals`, since it thinks that it has found new exports, possibly in an object literal, that need to be merged with the file's exports. For example: ```js (function() { exports.a = 1 module.exports = exports })() ```
1 parent b64d08a commit e379aeb

File tree

4 files changed

+68
-2
lines changed

4 files changed

+68
-2
lines changed

Diff for: src/compiler/checker.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -2353,11 +2353,16 @@ namespace ts {
23532353
function resolveExternalModuleSymbol(moduleSymbol: Symbol, dontResolveAlias?: boolean): Symbol;
23542354
function resolveExternalModuleSymbol(moduleSymbol: Symbol | undefined, dontResolveAlias?: boolean): Symbol | undefined;
23552355
function resolveExternalModuleSymbol(moduleSymbol: Symbol, dontResolveAlias?: boolean): Symbol {
2356-
return moduleSymbol && getMergedSymbol(getCommonJsExportEquals(resolveSymbol(moduleSymbol.exports!.get(InternalSymbolName.ExportEquals), dontResolveAlias), moduleSymbol)) || moduleSymbol;
2356+
if (moduleSymbol) {
2357+
const exportEquals = resolveSymbol(moduleSymbol.exports!.get(InternalSymbolName.ExportEquals), dontResolveAlias);
2358+
const exported = getCommonJsExportEquals(exportEquals, moduleSymbol);
2359+
return getMergedSymbol(exported) || moduleSymbol;
2360+
}
2361+
return undefined!;
23572362
}
23582363

23592364
function getCommonJsExportEquals(exported: Symbol | undefined, moduleSymbol: Symbol): Symbol | undefined {
2360-
if (!exported || exported === unknownSymbol || moduleSymbol.exports!.size === 1) {
2365+
if (!exported || exported === unknownSymbol || exported === moduleSymbol || moduleSymbol.exports!.size === 1) {
23612366
return exported;
23622367
}
23632368
const merged = cloneSymbol(exported);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
=== tests/cases/conformance/salsa/Eloquent.js ===
2+
// bug #27365, crashes from github.com/marijnh/Eloquent-JavaScript
3+
(function() {
4+
exports.bigOak = 1
5+
>exports.bigOak : Symbol(bigOak, Decl(Eloquent.js, 1, 13))
6+
>exports : Symbol(bigOak, Decl(Eloquent.js, 1, 13))
7+
>bigOak : Symbol(bigOak, Decl(Eloquent.js, 1, 13))
8+
9+
exports.everywhere = 2
10+
>exports.everywhere : Symbol(everywhere, Decl(Eloquent.js, 2, 18))
11+
>exports : Symbol(everywhere, Decl(Eloquent.js, 2, 18))
12+
>everywhere : Symbol(everywhere, Decl(Eloquent.js, 2, 18))
13+
14+
module.exports = exports
15+
>module.exports : Symbol("tests/cases/conformance/salsa/Eloquent", Decl(Eloquent.js, 0, 0))
16+
>module : Symbol(export=, Decl(Eloquent.js, 3, 22))
17+
>exports : Symbol(export=, Decl(Eloquent.js, 3, 22))
18+
>exports : Symbol("tests/cases/conformance/salsa/Eloquent", Decl(Eloquent.js, 0, 0))
19+
20+
})()
21+
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
=== tests/cases/conformance/salsa/Eloquent.js ===
2+
// bug #27365, crashes from github.com/marijnh/Eloquent-JavaScript
3+
(function() {
4+
>(function() {exports.bigOak = 1exports.everywhere = 2module.exports = exports})() : void
5+
>(function() {exports.bigOak = 1exports.everywhere = 2module.exports = exports}) : () => void
6+
>function() {exports.bigOak = 1exports.everywhere = 2module.exports = exports} : () => void
7+
8+
exports.bigOak = 1
9+
>exports.bigOak = 1 : 1
10+
>exports.bigOak : number
11+
>exports : typeof import("tests/cases/conformance/salsa/Eloquent")
12+
>bigOak : number
13+
>1 : 1
14+
15+
exports.everywhere = 2
16+
>exports.everywhere = 2 : 2
17+
>exports.everywhere : number
18+
>exports : typeof import("tests/cases/conformance/salsa/Eloquent")
19+
>everywhere : number
20+
>2 : 2
21+
22+
module.exports = exports
23+
>module.exports = exports : typeof import("tests/cases/conformance/salsa/Eloquent")
24+
>module.exports : typeof import("tests/cases/conformance/salsa/Eloquent")
25+
>module : { "tests/cases/conformance/salsa/Eloquent": typeof import("tests/cases/conformance/salsa/Eloquent"); }
26+
>exports : typeof import("tests/cases/conformance/salsa/Eloquent")
27+
>exports : typeof import("tests/cases/conformance/salsa/Eloquent")
28+
29+
})()
30+
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// @noEmit: true
2+
// @allowJs: true
3+
// @checkJs: true
4+
// @Filename: Eloquent.js
5+
// bug #27365, crashes from github.com/marijnh/Eloquent-JavaScript
6+
(function() {
7+
exports.bigOak = 1
8+
exports.everywhere = 2
9+
module.exports = exports
10+
})()

0 commit comments

Comments
 (0)