Skip to content

Commit

Permalink
[ts] Support import ... = and export = in scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolo-ribaudo committed Mar 15, 2023
1 parent a04c976 commit 07e71ed
Show file tree
Hide file tree
Showing 11 changed files with 58 additions and 21 deletions.
58 changes: 41 additions & 17 deletions packages/babel-plugin-transform-typescript/src/index.ts
Expand Up @@ -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<t.Program>;
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;
Expand Down Expand Up @@ -575,33 +590,42 @@ export default declare((api, opts: Options) => {
},

TSImportEqualsDeclaration(path: NodePath<t.TSImportEqualsDeclaration>) {
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 <value>;`.",
assertCjsModuleIsScript(
path,
`export = <value>;`,
`export default <value>;`,
);
path.replaceWith(
template.statement.ast`module.exports = ${path.node.expression}`,
);
},

Expand Down
@@ -0,0 +1 @@
export = 0;
@@ -0,0 +1,3 @@
{
"sourceType": "script"
}
@@ -0,0 +1 @@
module.exports = 0;
@@ -1,3 +1,3 @@
{
"throws": "`export =` is not supported by @babel/plugin-transform-typescript\nPlease consider using `export <value>;`."
"throws": "`export = <value>;` is only supported when \"sourceType\" is \"script\".\nPlease consider using `export default <value>;`"
}
@@ -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."
}
@@ -0,0 +1,2 @@
import lib = require("lib");
lib();
@@ -0,0 +1,3 @@
{
"sourceType": "script"
}
@@ -0,0 +1,2 @@
const lib = require("lib");
lib();

This file was deleted.

0 comments on commit 07e71ed

Please sign in to comment.