diff --git a/src/transformer/before/visitor/visit/visit-binary-expression.ts b/src/transformer/before/visitor/visit/visit-binary-expression.ts index 32b777d..e3dd4e9 100644 --- a/src/transformer/before/visitor/visit/visit-binary-expression.ts +++ b/src/transformer/before/visitor/visit/visit-binary-expression.ts @@ -8,13 +8,14 @@ import {nodeContainsSuper} from "../../../util/node-contains-super"; import {addExportModifier} from "../../../util/add-export-modifier"; import {isRequireCall} from "../../../util/is-require-call"; import {getModuleExportsFromRequireDataInContext} from "../../../util/get-module-exports-from-require-data-in-context"; +import {isExpression} from "../../../util/is-expression"; /** * Visits the given BinaryExpression * @param {BeforeVisitorOptions} options * @returns {VisitResult} */ -export function visitBinaryExpression ({node, sourceFile, context}: BeforeVisitorOptions): VisitResult { +export function visitBinaryExpression ({node, sourceFile, context, continuation}: BeforeVisitorOptions): VisitResult { // Check if the left-hand side contains exports. For example: 'exports = ...' or 'exports.foo = 1' or event 'module.exports = 1' const exportsData = getExportsData(node.left); const right = walkThroughFillerNodes(node.right); @@ -158,6 +159,7 @@ export function visitBinaryExpression ({node, sourceFile, context}: BeforeVisito // Convert it into an ExportAssignment instead if possible else { + // Check if the rightvalue represents a require(...) call. const requireData = isRequireCall(node.right, sourceFile, context); @@ -165,7 +167,14 @@ export function visitBinaryExpression ({node, sourceFile, context}: BeforeVisito if (!requireData.match) { if (!context.isDefaultExported) { context.markDefaultAsExported(); - context.addTrailingStatements(createExportAssignment(undefined, undefined, false, node.right)); + const continuationResult = continuation(node.right); + if (continuationResult == null || Array.isArray(continuationResult) || !isExpression(continuationResult)) { + return undefined; + } + + else { + context.addTrailingStatements(createExportAssignment(undefined, undefined, false, continuationResult)); + } } return undefined; } diff --git a/test/exports.test.ts b/test/exports.test.ts index e2f704b..7c072e7 100644 --- a/test/exports.test.ts +++ b/test/exports.test.ts @@ -483,6 +483,33 @@ test("Converts 'exports = require(...)' syntax into namespace re-exports if the ); }); +test("Converts 'exports = require(...)()' syntax into namespace import along with a default export if the required module has named exports. #1", t => { + const bundle = generateTransformerResult([ + { + entry: true, + fileName: "index.ts", + text: ` + module.exports = require("./foo")(); + ` + }, + { + entry: true, + fileName: "foo.ts", + text: ` + exports.readFileSync = () => {}; + ` + } + ]); + const [file] = bundle; + t.deepEqual( + formatCode(file.text), + formatCode(`\ + import * as foo from "./foo"; + export default foo(); + `) + ); +}); + test("Converts 'exports = require(...)' syntax into a default export if the required module has one. #1", t => { const bundle = generateTransformerResult([ { @@ -526,4 +553,24 @@ test("Converts 'exports = require(...)' syntax into a default export if the requ export {default} from "./foo"; `) ); +}); + +test("Converts 'exports = require(...)()' syntax into a default export if the required module is unknown. #2", t => { + const bundle = generateTransformerResult([ + { + entry: true, + fileName: "index.ts", + text: ` + module.exports = require("./foo")(); + ` + } + ]); + const [file] = bundle; + t.deepEqual( + formatCode(file.text), + formatCode(`\ + import foo from "./foo"; + export default foo(); + `) + ); }); \ No newline at end of file