diff --git a/compilers/swc.js b/compilers/swc.js new file mode 100644 index 000000000..f7edceb00 --- /dev/null +++ b/compilers/swc.js @@ -0,0 +1 @@ +module.exports = require('../dist/compilers/swc') diff --git a/package-lock.json b/package-lock.json index df7e8885d..a2c8ed088 100644 --- a/package-lock.json +++ b/package-lock.json @@ -336,6 +336,53 @@ "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", "dev": true }, + "@node-rs/helper": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@node-rs/helper/-/helper-0.4.0.tgz", + "integrity": "sha512-fSyHEXmlt/FueKqAYiGFCnkohnQBMQwUr6VYPeZEeVBAzQzhioS1WaRe2fSpOuRKIimCQEvxhQ6fwsYxYakfGA==", + "optional": true, + "requires": { + "tslib": "^2.0.1" + }, + "dependencies": { + "tslib": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", + "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==", + "optional": true + } + } + }, + "@swc/core": { + "version": "1.2.38", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.2.38.tgz", + "integrity": "sha512-t/LRT2IJ+e4Wydm6Ttgf7yjPVnuoqWs4HVtzYuk/3DFbFtECQOkrkcKJR5yorg9crxQ/Dbs2AAd5e15CXefBBw==", + "optional": true, + "requires": { + "@node-rs/helper": "^0.4.0", + "@swc/core-darwin": "^1.2.38", + "@swc/core-linux": "^1.2.38", + "@swc/core-win32": "^1.2.38" + } + }, + "@swc/core-darwin": { + "version": "1.2.38", + "resolved": "https://registry.npmjs.org/@swc/core-darwin/-/core-darwin-1.2.38.tgz", + "integrity": "sha512-Z+eFLZnBjt+q5Cs4lyjpbceJknSTyb0Ryhtcbw79ejM5GLWOUZawXQ0MKfIKjTVI3J3ixfY2oLkIoNwpxFrTAA==", + "optional": true + }, + "@swc/core-linux": { + "version": "1.2.38", + "resolved": "https://registry.npmjs.org/@swc/core-linux/-/core-linux-1.2.38.tgz", + "integrity": "sha512-eB4eovIjC7bPG+VStu64bkt0eZZV3pzZX3Zw4F1f5WnTMdYr4PEk4aQOUDHOxKdLhccalSDnCBTn5OtgGeUBFQ==", + "optional": true + }, + "@swc/core-win32": { + "version": "1.2.38", + "resolved": "https://registry.npmjs.org/@swc/core-win32/-/core-win32-1.2.38.tgz", + "integrity": "sha512-/i0LXfpsXHIc/T/M1uBkFxYFwld/EhhhLOfTs0tal4vP1jkjJm3hGMGhmY86JQhXL6B5PvmmTOhUbSUeg/K+VA==", + "optional": true + }, "@types/chai": { "version": "4.0.10", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.0.10.tgz", diff --git a/package.json b/package.json index e04ad3548..67824b74c 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,8 @@ "./esm": "./esm.mjs", "./esm.mjs": "./esm.mjs", "./esm/transpile-only": "./esm/transpile-only.mjs", - "./esm/transpile-only.mjs": "./esm/transpile-only.mjs" + "./esm/transpile-only.mjs": "./esm/transpile-only.mjs", + "./compilers/swc": "./compilers/swc.js" }, "types": "dist/index.d.ts", "bin": { @@ -107,9 +108,14 @@ "util.promisify": "^1.0.1" }, "peerDependencies": { + "@swc/core": ">=1.2.38", "typescript": ">=2.7" }, + "optionalDependencies": { + "@swc/core": ">=1.2.38" + }, "dependencies": { + "@swc/core": ">=1.2.38", "arg": "^4.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", diff --git a/src/compilers/swc.ts b/src/compilers/swc.ts new file mode 100644 index 000000000..acf8b8fec --- /dev/null +++ b/src/compilers/swc.ts @@ -0,0 +1,53 @@ +import type * as ts from 'typescript' +import * as swc from '@swc/core' +import { JscTarget } from '@swc/core' + +export const transpileModule: typeof ts.transpileModule = (input: string, transpileOptions: ts.TranspileOptions): ts.TranspileOutput => { + const compilerOptions = transpileOptions.compilerOptions! + const { fileName } = transpileOptions + const { esModuleInterop, sourceMap, importHelpers, experimentalDecorators, emitDecoratorMetadata, target, jsxFactory, jsxFragmentFactory } = compilerOptions + const { code, map } = swc.transformSync(input, { + filename: fileName, + sourceMaps: sourceMap, + // isModule: true, + module: { + type: 'commonjs', + noInterop: !esModuleInterop + }, + swcrc: false, + jsc: { + externalHelpers: importHelpers, + parser: { + syntax: 'typescript', + tsx: fileName!.endsWith('.tsx') || fileName!.endsWith('.jsx'), + decorators: experimentalDecorators, + dynamicImport: true + }, + target: targetMapping.get(target!) ?? 'es3', + transform: { + decoratorMetadata: emitDecoratorMetadata, + legacyDecorator: true, + react: { + throwIfNamespace: false, + development: false, + useBuiltins: false, + pragma: jsxFactory!, + pragmaFrag: jsxFragmentFactory!, + } + } + } + }) + return { outputText: code, sourceMapText: map } +} + +const targetMapping = new Map() +targetMapping.set(/* ts.ScriptTarget.ES3 */ 0, 'es3') +targetMapping.set(/* ts.ScriptTarget.ES5 */ 1, 'es5') +targetMapping.set(/* ts.ScriptTarget.ES2015 */ 2, 'es2015') +targetMapping.set(/* ts.ScriptTarget.ES2016 */ 3, 'es2016') +targetMapping.set(/* ts.ScriptTarget.ES2017 */ 4, 'es2017') +targetMapping.set(/* ts.ScriptTarget.ES2018 */ 5, 'es2018') +targetMapping.set(/* ts.ScriptTarget.ES2019 */ 6, 'es2019') +targetMapping.set(/* ts.ScriptTarget.ES2020 */ 7, 'es2019') +targetMapping.set(/* ts.ScriptTarget.ESNext */ 99, 'es2019') +targetMapping.set(/* ts.ScriptTarget.Latest */ 99, 'es2019')