diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 086ec9dd927a8..a256b632fac26 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2072,7 +2072,9 @@ namespace ts { function setCommonJsModuleIndicator(node: Node) { if (!file.commonJsModuleIndicator) { file.commonJsModuleIndicator = node; - bindSourceFileAsExternalModule(); + if (!file.externalModuleIndicator) { + bindSourceFileAsExternalModule(); + } } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 22ab44ee0898d..f2697fe0101db 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12791,7 +12791,10 @@ namespace ts { } // In JavaScript files, calls to any identifier 'require' are treated as external module imports - if (isInJavaScriptFile(node) && isRequireCall(node, /*checkArgumentIsStringLiteral*/true)) { + if (isInJavaScriptFile(node) && + isRequireCall(node, /*checkArgumentIsStringLiteral*/true) && + // Make sure require is not a local function + !resolveName(node.expression, (node.expression).text, SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined)) { return resolveExternalModuleTypeByLiteral(node.arguments[0]); } diff --git a/tests/baselines/reference/requireAsFunctionInExternalModule.js b/tests/baselines/reference/requireAsFunctionInExternalModule.js new file mode 100644 index 0000000000000..a8b14db31388b --- /dev/null +++ b/tests/baselines/reference/requireAsFunctionInExternalModule.js @@ -0,0 +1,37 @@ +//// [tests/cases/compiler/requireAsFunctionInExternalModule.ts] //// + +//// [c.js] +export default function require(a) { } +export function has(a) { return true } + +//// [m.js] +import require, { has } from "./c" +export function hello() { } +if (has('ember-debug')) { + require('ember-debug'); +} + +//// [m2.ts] +import { hello } from "./m"; +hello(); + + +//// [c.js] +"use strict"; +function require(a) { } +exports.__esModule = true; +exports["default"] = require; +function has(a) { return true; } +exports.has = has; +//// [m.js] +"use strict"; +var c_1 = require("./c"); +function hello() { } +exports.hello = hello; +if (c_1.has('ember-debug')) { + c_1["default"]('ember-debug'); +} +//// [m2.js] +"use strict"; +var m_1 = require("./m"); +m_1.hello(); diff --git a/tests/baselines/reference/requireAsFunctionInExternalModule.symbols b/tests/baselines/reference/requireAsFunctionInExternalModule.symbols new file mode 100644 index 0000000000000..2f44d6b661184 --- /dev/null +++ b/tests/baselines/reference/requireAsFunctionInExternalModule.symbols @@ -0,0 +1,31 @@ +=== tests/cases/compiler/c.js === +export default function require(a) { } +>require : Symbol(require, Decl(c.js, 0, 0)) +>a : Symbol(a, Decl(c.js, 0, 32)) + +export function has(a) { return true } +>has : Symbol(has, Decl(c.js, 0, 38)) +>a : Symbol(a, Decl(c.js, 1, 20)) + +=== tests/cases/compiler/m.js === +import require, { has } from "./c" +>require : Symbol(require, Decl(m.js, 0, 6)) +>has : Symbol(has, Decl(m.js, 0, 17)) + +export function hello() { } +>hello : Symbol(hello, Decl(m.js, 0, 34)) + +if (has('ember-debug')) { +>has : Symbol(has, Decl(m.js, 0, 17)) + + require('ember-debug'); +>require : Symbol(require, Decl(m.js, 0, 6)) +} + +=== tests/cases/compiler/m2.ts === +import { hello } from "./m"; +>hello : Symbol(hello, Decl(m2.ts, 0, 8)) + +hello(); +>hello : Symbol(hello, Decl(m2.ts, 0, 8)) + diff --git a/tests/baselines/reference/requireAsFunctionInExternalModule.types b/tests/baselines/reference/requireAsFunctionInExternalModule.types new file mode 100644 index 0000000000000..2ce5f3aed3860 --- /dev/null +++ b/tests/baselines/reference/requireAsFunctionInExternalModule.types @@ -0,0 +1,37 @@ +=== tests/cases/compiler/c.js === +export default function require(a) { } +>require : (a: any) => void +>a : any + +export function has(a) { return true } +>has : (a: any) => boolean +>a : any +>true : true + +=== tests/cases/compiler/m.js === +import require, { has } from "./c" +>require : (a: any) => void +>has : (a: any) => boolean + +export function hello() { } +>hello : () => void + +if (has('ember-debug')) { +>has('ember-debug') : boolean +>has : (a: any) => boolean +>'ember-debug' : "ember-debug" + + require('ember-debug'); +>require('ember-debug') : void +>require : (a: any) => void +>'ember-debug' : "ember-debug" +} + +=== tests/cases/compiler/m2.ts === +import { hello } from "./m"; +>hello : () => void + +hello(); +>hello() : void +>hello : () => void + diff --git a/tests/cases/compiler/requireAsFunctionInExternalModule.ts b/tests/cases/compiler/requireAsFunctionInExternalModule.ts new file mode 100644 index 0000000000000..1715090c329ee --- /dev/null +++ b/tests/cases/compiler/requireAsFunctionInExternalModule.ts @@ -0,0 +1,16 @@ +// @allowjs: true +// @outDir: dist +// @Filename: c.js +export default function require(a) { } +export function has(a) { return true } + +// @Filename: m.js +import require, { has } from "./c" +export function hello() { } +if (has('ember-debug')) { + require('ember-debug'); +} + +// @Filename: m2.ts +import { hello } from "./m"; +hello();