diff --git a/packages/babel-plugin-transform-typescript/src/index.ts b/packages/babel-plugin-transform-typescript/src/index.ts index 7913e0b78f9d..bcb9f6c7ff20 100644 --- a/packages/babel-plugin-transform-typescript/src/index.ts +++ b/packages/babel-plugin-transform-typescript/src/index.ts @@ -78,6 +78,21 @@ function safeRemove(path: NodePath) { path.opts.noScope = false; } +function assertCjsModuleIsScript( + path: NodePath, + wrong: string, + suggestion: string, + extra: string = "", +): void { + const programParent = path.find(p => p.isProgram()) as NodePath; + if (programParent.node.sourceType !== "script") { + throw path.buildCodeFrameError( + `\`${wrong}\` is only supported when "sourceType" is "script".\n` + + `Please consider using \`${suggestion}\`${extra}.`, + ); + } +} + export interface Options extends SyntaxOptions { /** @default true */ allowNamespaces?: boolean; @@ -575,33 +590,42 @@ export default declare((api, opts: Options) => { }, TSImportEqualsDeclaration(path: NodePath) { - if (t.isTSExternalModuleReference(path.node.moduleReference)) { + const { id, moduleReference } = path.node; + + let init: t.Expression; + let varKind: "var" | "const"; + if (t.isTSExternalModuleReference(moduleReference)) { // import alias = require('foo'); - throw path.buildCodeFrameError( - `\`import ${path.node.id.name} = require('${path.node.moduleReference.expression.value}')\` ` + - "is not supported by @babel/plugin-transform-typescript\n" + - "Please consider using " + - `\`import ${path.node.id.name} from '${path.node.moduleReference.expression.value}';\` alongside ` + - "Typescript's --allowSyntheticDefaultImports option.", + assertCjsModuleIsScript( + path, + `import ${id.name} = require(...);`, + `import ${id.name} from '...';`, + " alongside Typescript's --allowSyntheticDefaultImports option", ); + init = t.callExpression(t.identifier("require"), [ + moduleReference.expression, + ]); + varKind = "const"; + } else { + // import alias = Namespace; + init = entityNameToExpr(moduleReference); + varKind = "var"; } - // import alias = Namespace; path.replaceWith( - t.variableDeclaration("var", [ - t.variableDeclarator( - path.node.id, - entityNameToExpr(path.node.moduleReference), - ), - ]), + t.variableDeclaration(varKind, [t.variableDeclarator(id, init)]), ); path.scope.registerDeclaration(path); }, TSExportAssignment(path) { - throw path.buildCodeFrameError( - "`export =` is not supported by @babel/plugin-transform-typescript\n" + - "Please consider using `export ;`.", + assertCjsModuleIsScript( + path, + `export = ;`, + `export default ;`, + ); + path.replaceWith( + template.statement.ast`module.exports = ${path.node.expression}`, ); }, diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/exports/export=-script/input.ts b/packages/babel-plugin-transform-typescript/test/fixtures/exports/export=-script/input.ts new file mode 100644 index 000000000000..fbedae645eb3 --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/exports/export=-script/input.ts @@ -0,0 +1 @@ +export = 0; \ No newline at end of file diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/exports/export=-script/options.json b/packages/babel-plugin-transform-typescript/test/fixtures/exports/export=-script/options.json new file mode 100644 index 000000000000..b412ffe6712f --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/exports/export=-script/options.json @@ -0,0 +1,3 @@ +{ + "sourceType": "script" +} diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/exports/export=-script/output.js b/packages/babel-plugin-transform-typescript/test/fixtures/exports/export=-script/output.js new file mode 100644 index 000000000000..d5b2e8bb3efb --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/exports/export=-script/output.js @@ -0,0 +1 @@ +module.exports = 0; diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/exports/export=/options.json b/packages/babel-plugin-transform-typescript/test/fixtures/exports/export=/options.json index 9ba7cc5c5f3a..e2376e518413 100644 --- a/packages/babel-plugin-transform-typescript/test/fixtures/exports/export=/options.json +++ b/packages/babel-plugin-transform-typescript/test/fixtures/exports/export=/options.json @@ -1,3 +1,3 @@ { - "throws": "`export =` is not supported by @babel/plugin-transform-typescript\nPlease consider using `export ;`." + "throws": "`export = ;` is only supported when \"sourceType\" is \"script\".\nPlease consider using `export default ;`" } diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/imports/import=/input.ts b/packages/babel-plugin-transform-typescript/test/fixtures/imports/import=-module/input.ts similarity index 100% rename from packages/babel-plugin-transform-typescript/test/fixtures/imports/import=/input.ts rename to packages/babel-plugin-transform-typescript/test/fixtures/imports/import=-module/input.ts diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/imports/import=-module/options.json b/packages/babel-plugin-transform-typescript/test/fixtures/imports/import=-module/options.json new file mode 100644 index 000000000000..8f13c717fc76 --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/imports/import=-module/options.json @@ -0,0 +1,4 @@ +{ + "sourceType": "module", + "throws": "`import lib = require(...);` is only supported when \"sourceType\" is \"script\".\nPlease consider using `import lib from '...';` alongside Typescript's --allowSyntheticDefaultImports option." +} diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/imports/import=-script/input.ts b/packages/babel-plugin-transform-typescript/test/fixtures/imports/import=-script/input.ts new file mode 100644 index 000000000000..dc8b049669b3 --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/imports/import=-script/input.ts @@ -0,0 +1,2 @@ +import lib = require("lib"); +lib(); diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/imports/import=-script/options.json b/packages/babel-plugin-transform-typescript/test/fixtures/imports/import=-script/options.json new file mode 100644 index 000000000000..b412ffe6712f --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/imports/import=-script/options.json @@ -0,0 +1,3 @@ +{ + "sourceType": "script" +} diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/imports/import=-script/output.js b/packages/babel-plugin-transform-typescript/test/fixtures/imports/import=-script/output.js new file mode 100644 index 000000000000..2ddbce589436 --- /dev/null +++ b/packages/babel-plugin-transform-typescript/test/fixtures/imports/import=-script/output.js @@ -0,0 +1,2 @@ +const lib = require("lib"); +lib(); diff --git a/packages/babel-plugin-transform-typescript/test/fixtures/imports/import=/options.json b/packages/babel-plugin-transform-typescript/test/fixtures/imports/import=/options.json deleted file mode 100644 index fc8cd41e40a3..000000000000 --- a/packages/babel-plugin-transform-typescript/test/fixtures/imports/import=/options.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "throws": "`import lib = require('lib')` is not supported by @babel/plugin-transform-typescript\nPlease consider using `import lib from 'lib';` alongside Typescript's --allowSyntheticDefaultImports option." -}