@ts-liveserver/ts-transpiler
Advanced tools
Comparing version 0.0.4 to 0.0.5
@@ -8,2 +8,3 @@ import CommonJsTransformer from '../../src/transformers/CommonJsTransformer' | ||
const input = 'require("./hello.ts")' | ||
expect(await transformWithPlugin(input)).toMatchSnapshot() | ||
const output = 'import "./hello.ts";' | ||
@@ -13,3 +14,4 @@ expect(await transformWithPlugin(input)).toBe(output) | ||
it('Should convert default import to ES6', async () => { | ||
const input = 'const Hello = require("./hello.ts")' | ||
const input = 'var Hello = require("./hello.ts")' | ||
expect(await transformWithPlugin(input)).toMatchSnapshot() | ||
const output = 'import * as Hello from "./hello.ts";' | ||
@@ -20,12 +22,17 @@ expect(await transformWithPlugin(input)).toBe(output) | ||
const input = 'const { Hello } = require("./hello.ts")' | ||
expect(await transformWithPlugin(input)).toMatchSnapshot() | ||
/* | ||
const output = 'import { Hello } from "./hello.ts";' | ||
expect(await transformWithPlugin(input)).toBe(output) | ||
*/ | ||
}) | ||
it('Should convert require in sub-scope', async () => { | ||
const input = '{ const hello = require("hello.js") }' | ||
expect(await transformWithPlugin(input)).toMatchSnapshot() | ||
/* | ||
'import * as GENERATED_VAR_BY_TRANSFORMER_1 from "hello.js"; { const hello = GENERATED_VAR_BY_TRANSFORMER_1; }' | ||
const output = | ||
'import * as GENERATED_VAR_BY_TRANSFORMER_1 from "hello.js"; { const hello = GENERATED_VAR_BY_TRANSFORMER_1; }' | ||
expect(await transformWithPlugin(input)).toBe( | ||
await transformWithoutPlugin(output), | ||
) | ||
) */ | ||
}) | ||
@@ -36,10 +43,26 @@ }) | ||
const input = 'module.exports = require("./hello.js")' | ||
expect(await transformWithPlugin(input)).toMatchSnapshot() | ||
/* | ||
const output = 'export * from "./hello.js";' | ||
expect(await transformWithPlugin(input)).toBe(output) | ||
expect(await transformWithPlugin(input)).toBe(output) | ||
*/ | ||
}) | ||
}) | ||
describe('Exports', () => { | ||
it('Should convert named export', async () => { | ||
const input = 'module.exports.hello = Hello;' | ||
expect(await transformWithPlugin(input)).toMatchSnapshot() | ||
const output = ` | ||
var GENERATED_VAR_BY_TRANSFORMER_1; | ||
GENERATED_VAR_BY_TRANSFORMER_1 = Hello; | ||
export { GENERATED_VAR_BY_TRANSFORMER_1 as hello }; | ||
` | ||
expect(await transformWithPlugin(input)).toBe( | ||
await transformWithoutPlugin(output), | ||
) | ||
}) | ||
it('Should convert to default export to ES6', async () => { | ||
const input = 'module.exports = Hello' | ||
const output = 'export default Hello' | ||
expect(await transformWithPlugin(input)).toMatchSnapshot() | ||
const output = `var GENERATED_VAR_BY_TRANSFORMER_1; GENERATED_VAR_BY_TRANSFORMER_1 = Hello; export default GENERATED_VAR_BY_TRANSFORMER_1;` | ||
expect(await transformWithPlugin(input)).toBe( | ||
@@ -51,31 +74,23 @@ await transformWithoutPlugin(output), | ||
const input = 'exports.hello = Hello' | ||
const output = 'export { Hello as hello }' | ||
expect(await transformWithPlugin(input)).toBe( | ||
await transformWithoutPlugin(output), | ||
) | ||
expect(await transformWithPlugin(input)).toMatchSnapshot() | ||
}) | ||
it('Should move exports to top scope', async () => { | ||
const input = '{ exports = Hello }' | ||
const output = ` | ||
var GENERATED_VAR_BY_TRANSFORMER_1; | ||
{ GENERATED_VAR_BY_TRANSFORMER_1 = Hello} | ||
export default GENERATED_VAR_BY_TRANSFORMER_1; | ||
const input = ` | ||
if (typeof define === 'function' && define.amd) { | ||
define(function () { | ||
return LZString; | ||
}) | ||
} else if (typeof module !== 'undefined' && module != null) { | ||
module.exports = LZString; | ||
} | ||
` | ||
expect(await transformWithPlugin(input)).toBe( | ||
await transformWithoutPlugin(output), | ||
) | ||
expect(await transformWithPlugin(input)).toMatchSnapshot() | ||
}) | ||
it('Should convert exports.name with same name as the parameter', async () => { | ||
const input = 'const hello = null; exports.hello = hello' | ||
const output = 'const hello = null; export { hello }' | ||
expect(await transformWithPlugin(input)).toBe( | ||
await transformWithoutPlugin(output), | ||
) | ||
expect(await transformWithPlugin(input)).toMatchSnapshot() | ||
}) | ||
it('Should convert exports.default', async () => { | ||
const input = 'exports.default = Hello' | ||
const output = 'export default Hello' | ||
expect(await transformWithPlugin(input)).toBe( | ||
await transformWithoutPlugin(output), | ||
) | ||
expect(await transformWithPlugin(input)).toMatchSnapshot() | ||
}) | ||
@@ -85,18 +100,19 @@ it('Should convert define.property with getter', async () => { | ||
'Object.defineProperty(exports, "hello", { enumerable: true, get: function () { return parts_js_1.PropertyPart; } });' | ||
const output = | ||
'var GENERATED_VAR_BY_TRANSFORMER_1 = parts_js_1.PropertyPart; export { GENERATED_VAR_BY_TRANSFORMER_1 as hello };' | ||
expect(await transformWithPlugin(input)).toBe( | ||
await transformWithoutPlugin(output), | ||
) | ||
expect(await transformWithPlugin(input)).toMatchSnapshot() | ||
}) | ||
it('Should convert define.property for identifier', async () => { | ||
const input = 'Object.defineProperty(exports, "a", b });' | ||
const output = 'export { b as a };' | ||
expect(await transformWithPlugin(input)).toBe( | ||
await transformWithoutPlugin(output), | ||
) | ||
expect(await transformWithPlugin(input)).toMatchSnapshot() | ||
}) | ||
it('Should convert define.property', async () => { | ||
it('Should convert ObjectLiteralExpression', async () => { | ||
const input = 'module.exports = { a: b, c: d }' | ||
const output = 'export { b as a, d as c };' | ||
expect(await transformWithPlugin(input)).toMatchSnapshot() | ||
const output = ` | ||
var GENERATED_VAR_BY_TRANSFORMER_1; | ||
var GENERATED_VAR_BY_TRANSFORMER_2; | ||
GENERATED_VAR_BY_TRANSFORMER_1 = b; | ||
GENERATED_VAR_BY_TRANSFORMER_2 = d; | ||
export { GENERATED_VAR_BY_TRANSFORMER_1 as a }; | ||
export { GENERATED_VAR_BY_TRANSFORMER_2 as c }; | ||
` | ||
expect(await transformWithPlugin(input)).toBe( | ||
@@ -106,7 +122,2 @@ await transformWithoutPlugin(output), | ||
}) | ||
it('Should convert to default export', async () => { | ||
const input = 'module.exports.hello = Hello;' | ||
const output = 'export { Hello as hello };' | ||
expect(await transformWithPlugin(input)).toBe(output) | ||
}) | ||
}) | ||
@@ -113,0 +124,0 @@ }) |
@@ -13,4 +13,4 @@ import TypeScript from 'typescript'; | ||
private stripModule; | ||
private exportsTopScope; | ||
private stripWildcardExports; | ||
private requireTopScope; | ||
} |
@@ -20,10 +20,11 @@ "use strict"; | ||
transformSourceFile(sourceFile) { | ||
const requireInTopScope = this.requireTopScope(sourceFile); | ||
const withoutModule = this.stripModule(requireInTopScope); | ||
const withoutModule = this.stripModule(sourceFile); | ||
const withoutDefineProperty = this.convertDefinePropery(withoutModule); | ||
const exportsTopScope = this.exportsTopScope(withoutDefineProperty); | ||
const esmExport = this.convertToEsmExport(exportsTopScope); | ||
const withoutWildcardExports = this.stripWildcardExports(withoutDefineProperty); | ||
const requireInTopScope = this.requireTopScope(withoutWildcardExports); | ||
// const exportsTopScope = this.exportsTopScope(requireInTopScope) | ||
const esmExport = this.convertToEsmExport(requireInTopScope); | ||
return this.convertToEsmImport(esmExport); | ||
} | ||
// Generate a file unique variable name | ||
// Generate a file-unique variable name | ||
generateUniqueName() { | ||
@@ -76,3 +77,3 @@ this.counter++; | ||
} | ||
// Top level CommonJS to ESM | ||
// Top level CommonJS to ESM. const hello = require('hello') | ||
convertToEsmImport(sourceFile) { | ||
@@ -130,4 +131,6 @@ const visit = (node) => { | ||
} | ||
// Top level CommonJS to ESM | ||
// exports.hello = something -> export { something as hello } | ||
convertToEsmExport(sourceFile) { | ||
const newTopStatements = []; | ||
const newBottomStatements = []; | ||
const visit = (node) => { | ||
@@ -142,60 +145,27 @@ if (typescript_1.default.isExpressionStatement(node) && | ||
node.expression.left.expression.text === KEYNAME_EXPORTS) { | ||
const newIdentifierName = this.generateUniqueName(); | ||
const identifier = typescript_1.default.factory.createIdentifier(newIdentifierName); | ||
newTopStatements.push(typescript_1.default.factory.createVariableStatement(undefined, [ | ||
typescript_1.default.factory.createVariableDeclaration(newIdentifierName, undefined, undefined, undefined), | ||
])); | ||
// exports.default = something; | ||
if (node.expression.left.name.text === 'default') { | ||
return typescript_1.default.factory.createExportAssignment(undefined, undefined, undefined, node.expression.right); | ||
newBottomStatements.push(typescript_1.default.factory.createExportAssignment(undefined, undefined, undefined, identifier)); | ||
} | ||
// exports.something = anIdentifier; | ||
else if (typescript_1.default.isIdentifier(node.expression.right)) { | ||
return typescript_1.default.factory.createExportDeclaration(undefined, undefined, false, typescript_1.default.factory.createNamedExports([ | ||
typescript_1.default.factory.createExportSpecifier(node.expression.right.text === node.expression.left.name.text | ||
? undefined | ||
: node.expression.right, node.expression.left.name), | ||
])); | ||
} | ||
else { | ||
const newIdentifierName = this.generateUniqueName(); | ||
const variableStatement = typescript_1.default.factory.createVariableStatement(undefined, [ | ||
typescript_1.default.factory.createVariableDeclaration(newIdentifierName, undefined, undefined, node.expression.right), | ||
]); | ||
return [ | ||
variableStatement, | ||
typescript_1.default.factory.createExportDeclaration(undefined, undefined, false, typescript_1.default.factory.createNamedExports([ | ||
typescript_1.default.factory.createExportSpecifier(typescript_1.default.factory.createIdentifier(newIdentifierName), node.expression.left.name), | ||
])), | ||
]; | ||
newBottomStatements.push(typescript_1.default.factory.createExportDeclaration(undefined, undefined, false, typescript_1.default.factory.createNamedExports([ | ||
typescript_1.default.factory.createExportSpecifier(newIdentifierName, node.expression.left.name), | ||
]))); | ||
} | ||
return typescript_1.default.factory.createExpressionStatement(typescript_1.default.factory.createBinaryExpression(identifier, node.expression.operatorToken, node.expression.right)); | ||
} | ||
// exports = something; | ||
if (typescript_1.default.isIdentifier(node.expression.left) && | ||
node.expression.left.text === KEYNAME_EXPORTS) { | ||
// exports = { a: false, b: true } | ||
if (typescript_1.default.isObjectLiteralExpression(node.expression.right)) { | ||
const exportSpecifiers = []; | ||
for (const property of node.expression.right.properties) { | ||
if (typescript_1.default.isPropertyAssignment(property) && | ||
typescript_1.default.isIdentifier(property.name) && | ||
typescript_1.default.isIdentifier(property.initializer)) { | ||
exportSpecifiers.push(typescript_1.default.factory.createExportSpecifier(property.initializer.text === property.name.text | ||
? undefined | ||
: property.initializer, property.name)); | ||
} | ||
} | ||
return typescript_1.default.factory.createExportDeclaration(undefined, undefined, false, typescript_1.default.factory.createNamedExports(exportSpecifiers)); | ||
} | ||
// exports = require('hello.js'); | ||
else if (typescript_1.default.isCallExpression(node.expression.right) && | ||
typescript_1.default.isIdentifier(node.expression.right.expression) && | ||
node.expression.right.expression.text === 'require' && | ||
typescript_1.default.isStringLiteral(node.expression.right.arguments[0])) { | ||
return typescript_1.default.factory.createExportDeclaration(undefined, undefined, false, undefined, node.expression.right.arguments[0]); | ||
} | ||
// exports = 'hello' or exports = Hello | ||
else { | ||
return typescript_1.default.factory.createExportAssignment(undefined, undefined, undefined, node.expression.right); | ||
} | ||
} | ||
} | ||
return node; | ||
return typescript_1.default.visitEachChild(node, visit, this.context); | ||
}; | ||
return typescript_1.default.visitEachChild(sourceFile, visit, this.context); | ||
const changedSourceFile = typescript_1.default.visitNode(sourceFile, visit); | ||
return typescript_1.default.factory.updateSourceFile(changedSourceFile, [ | ||
...newTopStatements, | ||
...changedSourceFile.statements, | ||
...newBottomStatements, | ||
]); | ||
} | ||
@@ -210,3 +180,3 @@ // module.exports -> exports | ||
node.name.text === KEYNAME_EXPORTS) { | ||
return node.name; | ||
return typescript_1.default.factory.createIdentifier(node.name.text); | ||
} | ||
@@ -217,29 +187,32 @@ return typescript_1.default.visitEachChild(node, visit, this.context); | ||
} | ||
// Move all require-calls to top-scope | ||
exportsTopScope(sourceFile) { | ||
const newTopStatements = []; | ||
const newBottomStatements = []; | ||
// exports = hello -> export.default = hello | ||
// exports = { a: 'a' } -> exports.a = 'a'; | ||
stripWildcardExports(sourceFile) { | ||
const visit = (node) => { | ||
const inRootScope = node?.parent?.parent && typescript_1.default.isSourceFile(node.parent.parent); | ||
if (inRootScope === false && | ||
typescript_1.default.isBinaryExpression(node) && | ||
typescript_1.default.isIdentifier(node.left) && | ||
node.left.text === KEYNAME_EXPORTS && | ||
node.operatorToken.kind === typescript_1.default.SyntaxKind.EqualsToken) { | ||
const newIdentifierName = this.generateUniqueName(); | ||
const newIdentifier = typescript_1.default.factory.createIdentifier(newIdentifierName); | ||
newTopStatements.push(typescript_1.default.factory.createVariableStatement(undefined, [ | ||
typescript_1.default.factory.createVariableDeclaration(newIdentifierName, undefined, undefined, undefined), | ||
])); | ||
newBottomStatements.push(typescript_1.default.factory.createExpressionStatement(typescript_1.default.factory.createBinaryExpression(node.left, node.operatorToken, newIdentifier))); | ||
return typescript_1.default.factory.createBinaryExpression(newIdentifier, node.operatorToken, node.right); | ||
// exports = SOMETHING | ||
if (typescript_1.default.isExpressionStatement(node) && | ||
typescript_1.default.isBinaryExpression(node.expression) && | ||
node.expression.operatorToken.kind === | ||
typescript_1.default.SyntaxKind.EqualsToken && | ||
typescript_1.default.isIdentifier(node.expression.left) && | ||
node.expression.left.text === KEYNAME_EXPORTS) { | ||
// exports = { a: 'a' } | ||
if (typescript_1.default.isObjectLiteralExpression(node.expression.right)) { | ||
const expressions = []; | ||
for (const property of node.expression.right.properties) { | ||
if (typescript_1.default.isPropertyAssignment(property) && | ||
typescript_1.default.isIdentifier(property.name)) { | ||
expressions.push(typescript_1.default.factory.createExpressionStatement(typescript_1.default.factory.createBinaryExpression(typescript_1.default.factory.createPropertyAccessExpression(typescript_1.default.factory.createIdentifier(KEYNAME_EXPORTS), typescript_1.default.factory.createIdentifier(property.name.text)), node.expression.operatorToken, property.initializer))); | ||
} | ||
} | ||
return expressions; | ||
} | ||
// exports = Something | ||
else { | ||
return typescript_1.default.factory.createExpressionStatement(typescript_1.default.factory.createBinaryExpression(typescript_1.default.factory.createPropertyAccessExpression(typescript_1.default.factory.createIdentifier(KEYNAME_EXPORTS), typescript_1.default.factory.createIdentifier('default')), node.expression.operatorToken, node.expression.right)); | ||
} | ||
} | ||
return typescript_1.default.visitEachChild(node, visit, this.context); | ||
}; | ||
const changedSourceFile = typescript_1.default.visitNode(sourceFile, visit); | ||
return typescript_1.default.factory.updateSourceFile(changedSourceFile, [ | ||
...newTopStatements, | ||
...changedSourceFile.statements, | ||
...newBottomStatements, | ||
]); | ||
return typescript_1.default.visitNode(sourceFile, visit); | ||
} | ||
@@ -246,0 +219,0 @@ // Move all require-calls to top-scope |
@@ -73,2 +73,3 @@ "use strict"; | ||
} | ||
// Empty functions | ||
if (typescript_1.default.isExpressionStatement(node) && | ||
@@ -75,0 +76,0 @@ typescript_1.default.isCallExpression(node.expression) && |
{ | ||
"name": "@ts-liveserver/ts-transpiler", | ||
"version": "0.0.4", | ||
"version": "0.0.5", | ||
"main": "dist/index.js", | ||
@@ -9,2 +9,3 @@ "scripts": { | ||
"test:watch": "jest --watch", | ||
"test:update-snapshot": "jest --updateSnapshot", | ||
"test": "jest" | ||
@@ -11,0 +12,0 @@ }, |
@@ -20,10 +20,13 @@ import TypeScript from 'typescript' | ||
): TypeScript.SourceFile { | ||
const requireInTopScope = this.requireTopScope(sourceFile) | ||
const withoutModule = this.stripModule(requireInTopScope) | ||
const withoutModule = this.stripModule(sourceFile) | ||
const withoutDefineProperty = this.convertDefinePropery(withoutModule) | ||
const exportsTopScope = this.exportsTopScope(withoutDefineProperty) | ||
const esmExport = this.convertToEsmExport(exportsTopScope) | ||
const withoutWildcardExports = this.stripWildcardExports( | ||
withoutDefineProperty, | ||
) | ||
const requireInTopScope = this.requireTopScope(withoutWildcardExports) | ||
// const exportsTopScope = this.exportsTopScope(requireInTopScope) | ||
const esmExport = this.convertToEsmExport(requireInTopScope) | ||
return this.convertToEsmImport(esmExport) | ||
} | ||
// Generate a file unique variable name | ||
// Generate a file-unique variable name | ||
private generateUniqueName() { | ||
@@ -103,3 +106,3 @@ this.counter++ | ||
} | ||
// Top level CommonJS to ESM | ||
// Top level CommonJS to ESM. const hello = require('hello') | ||
private convertToEsmImport( | ||
@@ -213,6 +216,11 @@ sourceFile: TypeScript.SourceFile, | ||
} | ||
// Top level CommonJS to ESM | ||
// exports.hello = something -> export { something as hello } | ||
private convertToEsmExport( | ||
sourceFile: TypeScript.SourceFile, | ||
): TypeScript.SourceFile { | ||
const newTopStatements: TypeScript.VariableStatement[] = [] | ||
const newBottomStatements: ( | ||
| TypeScript.ExportDeclaration | ||
| TypeScript.ExportAssignment | ||
)[] = [] | ||
const visit = ( | ||
@@ -233,41 +241,28 @@ node: TypeScript.Node, | ||
) { | ||
const newIdentifierName = this.generateUniqueName() | ||
const identifier = TypeScript.factory.createIdentifier( | ||
newIdentifierName, | ||
) | ||
newTopStatements.push( | ||
TypeScript.factory.createVariableStatement(undefined, [ | ||
TypeScript.factory.createVariableDeclaration( | ||
newIdentifierName, | ||
undefined, | ||
undefined, | ||
undefined, | ||
), | ||
]), | ||
) | ||
// exports.default = something; | ||
if (node.expression.left.name.text === 'default') { | ||
return TypeScript.factory.createExportAssignment( | ||
undefined, | ||
undefined, | ||
undefined, | ||
node.expression.right, | ||
newBottomStatements.push( | ||
TypeScript.factory.createExportAssignment( | ||
undefined, | ||
undefined, | ||
undefined, | ||
identifier, | ||
), | ||
) | ||
} | ||
// exports.something = anIdentifier; | ||
else if (TypeScript.isIdentifier(node.expression.right)) { | ||
return TypeScript.factory.createExportDeclaration( | ||
undefined, | ||
undefined, | ||
false, | ||
TypeScript.factory.createNamedExports([ | ||
TypeScript.factory.createExportSpecifier( | ||
node.expression.right.text === node.expression.left.name.text | ||
? undefined | ||
: node.expression.right, | ||
node.expression.left.name, | ||
), | ||
]), | ||
) | ||
} else { | ||
const newIdentifierName = this.generateUniqueName() | ||
const variableStatement = TypeScript.factory.createVariableStatement( | ||
undefined, | ||
[ | ||
TypeScript.factory.createVariableDeclaration( | ||
newIdentifierName, | ||
undefined, | ||
undefined, | ||
node.expression.right, | ||
), | ||
], | ||
) | ||
return [ | ||
variableStatement, | ||
newBottomStatements.push( | ||
TypeScript.factory.createExportDeclaration( | ||
@@ -279,3 +274,3 @@ undefined, | ||
TypeScript.factory.createExportSpecifier( | ||
TypeScript.factory.createIdentifier(newIdentifierName), | ||
newIdentifierName, | ||
node.expression.left.name, | ||
@@ -285,65 +280,21 @@ ), | ||
), | ||
] | ||
} | ||
} | ||
// exports = something; | ||
if ( | ||
TypeScript.isIdentifier(node.expression.left) && | ||
node.expression.left.text === KEYNAME_EXPORTS | ||
) { | ||
// exports = { a: false, b: true } | ||
if (TypeScript.isObjectLiteralExpression(node.expression.right)) { | ||
const exportSpecifiers: TypeScript.ExportSpecifier[] = [] | ||
for (const property of node.expression.right.properties) { | ||
if ( | ||
TypeScript.isPropertyAssignment(property) && | ||
TypeScript.isIdentifier(property.name) && | ||
TypeScript.isIdentifier(property.initializer) | ||
) { | ||
exportSpecifiers.push( | ||
TypeScript.factory.createExportSpecifier( | ||
property.initializer.text === property.name.text | ||
? undefined | ||
: property.initializer, | ||
property.name, | ||
), | ||
) | ||
} | ||
} | ||
return TypeScript.factory.createExportDeclaration( | ||
undefined, | ||
undefined, | ||
false, | ||
TypeScript.factory.createNamedExports(exportSpecifiers), | ||
) | ||
} | ||
// exports = require('hello.js'); | ||
else if ( | ||
TypeScript.isCallExpression(node.expression.right) && | ||
TypeScript.isIdentifier(node.expression.right.expression) && | ||
node.expression.right.expression.text === 'require' && | ||
TypeScript.isStringLiteral(node.expression.right.arguments[0]) | ||
) { | ||
return TypeScript.factory.createExportDeclaration( | ||
undefined, | ||
undefined, | ||
false, | ||
undefined, | ||
node.expression.right.arguments[0], | ||
) | ||
} | ||
// exports = 'hello' or exports = Hello | ||
else { | ||
return TypeScript.factory.createExportAssignment( | ||
undefined, | ||
undefined, | ||
undefined, | ||
return TypeScript.factory.createExpressionStatement( | ||
TypeScript.factory.createBinaryExpression( | ||
identifier, | ||
node.expression.operatorToken, | ||
node.expression.right, | ||
) | ||
} | ||
), | ||
) | ||
} | ||
} | ||
return node | ||
return TypeScript.visitEachChild(node, visit, this.context) | ||
} | ||
return TypeScript.visitEachChild(sourceFile, visit, this.context) | ||
const changedSourceFile = TypeScript.visitNode(sourceFile, visit) | ||
return TypeScript.factory.updateSourceFile(changedSourceFile, [ | ||
...newTopStatements, | ||
...changedSourceFile.statements, | ||
...newBottomStatements, | ||
]) | ||
} | ||
@@ -362,3 +313,3 @@ // module.exports -> exports | ||
) { | ||
return node.name | ||
return TypeScript.factory.createIdentifier(node.name.text) | ||
} | ||
@@ -369,55 +320,60 @@ return TypeScript.visitEachChild(node, visit, this.context) | ||
} | ||
// Move all require-calls to top-scope | ||
private exportsTopScope( | ||
// exports = hello -> export.default = hello | ||
// exports = { a: 'a' } -> exports.a = 'a'; | ||
private stripWildcardExports( | ||
sourceFile: TypeScript.SourceFile, | ||
): TypeScript.SourceFile { | ||
const newTopStatements: TypeScript.VariableStatement[] = [] | ||
const newBottomStatements: TypeScript.Statement[] = [] | ||
const visit = (node: TypeScript.Node): TypeScript.Node => { | ||
const inRootScope = | ||
node?.parent?.parent && TypeScript.isSourceFile(node.parent.parent) | ||
const visit = ( | ||
node: TypeScript.Node, | ||
): TypeScript.Node | TypeScript.Node[] => { | ||
// exports = SOMETHING | ||
if ( | ||
inRootScope === false && | ||
TypeScript.isBinaryExpression(node) && | ||
TypeScript.isIdentifier(node.left) && | ||
node.left.text === KEYNAME_EXPORTS && | ||
node.operatorToken.kind === TypeScript.SyntaxKind.EqualsToken | ||
TypeScript.isExpressionStatement(node) && | ||
TypeScript.isBinaryExpression(node.expression) && | ||
node.expression.operatorToken.kind === | ||
TypeScript.SyntaxKind.EqualsToken && | ||
TypeScript.isIdentifier(node.expression.left) && | ||
node.expression.left.text === KEYNAME_EXPORTS | ||
) { | ||
const newIdentifierName = this.generateUniqueName() | ||
const newIdentifier = TypeScript.factory.createIdentifier( | ||
newIdentifierName, | ||
) | ||
newTopStatements.push( | ||
TypeScript.factory.createVariableStatement(undefined, [ | ||
TypeScript.factory.createVariableDeclaration( | ||
newIdentifierName, | ||
undefined, | ||
undefined, | ||
undefined, | ||
), | ||
]), | ||
) | ||
newBottomStatements.push( | ||
TypeScript.factory.createExpressionStatement( | ||
// exports = { a: 'a' } | ||
if (TypeScript.isObjectLiteralExpression(node.expression.right)) { | ||
const expressions: TypeScript.ExpressionStatement[] = [] | ||
for (const property of node.expression.right.properties) { | ||
if ( | ||
TypeScript.isPropertyAssignment(property) && | ||
TypeScript.isIdentifier(property.name) | ||
) { | ||
expressions.push( | ||
TypeScript.factory.createExpressionStatement( | ||
TypeScript.factory.createBinaryExpression( | ||
TypeScript.factory.createPropertyAccessExpression( | ||
TypeScript.factory.createIdentifier(KEYNAME_EXPORTS), | ||
TypeScript.factory.createIdentifier(property.name.text), | ||
), | ||
node.expression.operatorToken, | ||
property.initializer, | ||
), | ||
), | ||
) | ||
} | ||
} | ||
return expressions | ||
} | ||
// exports = Something | ||
else { | ||
return TypeScript.factory.createExpressionStatement( | ||
TypeScript.factory.createBinaryExpression( | ||
node.left, | ||
node.operatorToken, | ||
newIdentifier, | ||
TypeScript.factory.createPropertyAccessExpression( | ||
TypeScript.factory.createIdentifier(KEYNAME_EXPORTS), | ||
TypeScript.factory.createIdentifier('default'), | ||
), | ||
node.expression.operatorToken, | ||
node.expression.right, | ||
), | ||
), | ||
) | ||
return TypeScript.factory.createBinaryExpression( | ||
newIdentifier, | ||
node.operatorToken, | ||
node.right, | ||
) | ||
) | ||
} | ||
} | ||
return TypeScript.visitEachChild(node, visit, this.context) | ||
} | ||
const changedSourceFile = TypeScript.visitNode(sourceFile, visit) | ||
return TypeScript.factory.updateSourceFile(changedSourceFile, [ | ||
...newTopStatements, | ||
...changedSourceFile.statements, | ||
...newBottomStatements, | ||
]) | ||
return TypeScript.visitNode(sourceFile, visit) | ||
} | ||
@@ -424,0 +380,0 @@ // Move all require-calls to top-scope |
@@ -90,2 +90,3 @@ import TypeScript from 'typescript' | ||
} | ||
// Empty functions | ||
if ( | ||
@@ -92,0 +93,0 @@ TypeScript.isExpressionStatement(node) && |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
124099
59
2580
6