diff --git a/package-lock.json b/package-lock.json index 849393ce9..b0cba38d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -353,6 +353,30 @@ "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", "dev": true }, + "@napi-rs/triples": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@napi-rs/triples/-/triples-1.0.2.tgz", + "integrity": "sha512-EL3SiX43m9poFSnhDx4d4fn9SSaqyO2rHsCNhETi9bWPmjXK3uPJ0QpPFtx39FEdHcz1vJmsiW41kqc0AgvtzQ==", + "dev": true + }, + "@node-rs/helper": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@node-rs/helper/-/helper-1.1.0.tgz", + "integrity": "sha512-r43YnnrY5JNzDuXJdW3sBJrKzvejvFmFWbiItUEoBJsaPzOIWFMhXB7i5j4c9EMXcFfxveF4l7hT+rLmwtjrVQ==", + "dev": true, + "requires": { + "@napi-rs/triples": "^1.0.2", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", + "dev": true + } + } + }, "@nodelib/fs.scandir": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", @@ -385,6 +409,93 @@ "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", "dev": true }, + "@swc/core": { + "version": "1.2.48", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.2.48.tgz", + "integrity": "sha512-gL8Xy61wp4w35OLCTdUHx+B8/iiL7yoNejw3Kbd3Cm4ajf/rGXlM8nACuD3O9+Ilgw4uqIwYWr9SP4APBSloOQ==", + "dev": true, + "requires": { + "@node-rs/helper": "^1.0.0", + "@swc/core-android-arm64": "^1.2.48", + "@swc/core-darwin-arm64": "^1.2.48", + "@swc/core-darwin-x64": "^1.2.48", + "@swc/core-linux-arm-gnueabihf": "^1.2.48", + "@swc/core-linux-arm64-gnu": "^1.2.48", + "@swc/core-linux-x64-gnu": "^1.2.48", + "@swc/core-linux-x64-musl": "^1.2.48", + "@swc/core-win32-ia32-msvc": "^1.2.48", + "@swc/core-win32-x64-msvc": "^1.2.48" + } + }, + "@swc/core-android-arm64": { + "version": "1.2.48", + "resolved": "https://registry.npmjs.org/@swc/core-android-arm64/-/core-android-arm64-1.2.48.tgz", + "integrity": "sha512-/aRdn5RBHNRaPh8GRZ6pJQRevqYpWdvlW7hkh5XPAqYotiL7DeL5KzWuW8wBZlDQuLZ3/i3LLE/ts/HzhdxQ5Q==", + "dev": true, + "optional": true + }, + "@swc/core-darwin-arm64": { + "version": "1.2.48", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.2.48.tgz", + "integrity": "sha512-OzGVZ9kB1Wg6sRFLkvRVVFiEFcpyHagkr4sZQi7F6J8H7kBQji8J6j4Xm7thNeD0dkHeF3m3iN6SDyphp/fC4Q==", + "dev": true, + "optional": true + }, + "@swc/core-darwin-x64": { + "version": "1.2.48", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.2.48.tgz", + "integrity": "sha512-rlwDBEY8qSLVEODUG++qWIig79CxpGCQS4ZG56FsjApEYKZ27Pi04eF+K2eN6Nr9DtxDD2fIIR8hZUn37sRf7w==", + "dev": true, + "optional": true + }, + "@swc/core-linux-arm-gnueabihf": { + "version": "1.2.48", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.2.48.tgz", + "integrity": "sha512-XRl3Xa3uie9kRC3o+WhQtqfQ6FOBDnq5KqIdTXxXJYFjjGCq5lpNnJG61kRSh+AoQtvCcbL07peozQ5ThzCbKA==", + "dev": true, + "optional": true + }, + "@swc/core-linux-arm64-gnu": { + "version": "1.2.48", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.2.48.tgz", + "integrity": "sha512-wbhFe++C0Q9mRlu7HJZtezEFpPVAMwJUWRIebi7uMQNjKnnJDIbQQA/4LFO3JEHMsyqkDAbV2N6ZnQdyYnrilQ==", + "dev": true, + "optional": true + }, + "@swc/core-linux-x64-gnu": { + "version": "1.2.48", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.2.48.tgz", + "integrity": "sha512-4bMqUsP7yUWCRkPLl8peNgC/dclUMGV8quHvs7Tv/JAV1sV9JGZ+0RrtUaT0hd6cx7T/zhJDkuz+eArCac8tqQ==", + "dev": true, + "optional": true + }, + "@swc/core-linux-x64-musl": { + "version": "1.2.48", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.2.48.tgz", + "integrity": "sha512-yHV314AkFoGEmqMFBYXqqzDG5PGfYHwXHH9H6ErKE6anJMEPcICCrROk7gCzAu3yTSoIkT0mEUn+33vnded6ig==", + "dev": true, + "optional": true + }, + "@swc/core-win32-ia32-msvc": { + "version": "1.2.48", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.2.48.tgz", + "integrity": "sha512-wytnwb7Yby+Skpf6uSeQIJNG14NZax1NVApTUs4Lguw+ibUPJvFHlaMjnZwugQqbV80vpCUZQMXRa5MwZwZo/w==", + "dev": true, + "optional": true + }, + "@swc/core-win32-x64-msvc": { + "version": "1.2.48", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.2.48.tgz", + "integrity": "sha512-3/Ec4rtZwt3BQZVsSOe47ahY4YlxHxdslCsOnsQ7hMe1ynMvq47Lo1DAX8J6r7YfthYG6HUrM5qHDIxpCgAftA==", + "dev": true, + "optional": true + }, + "@swc/wasm": { + "version": "1.2.48", + "resolved": "https://registry.npmjs.org/@swc/wasm/-/wasm-1.2.48.tgz", + "integrity": "sha512-Nn9Y6dIVETcBXjQkYZUtijppvOwRUXmYJLENK1hpgMP4BiGJJ/UrM5yp4YgRWWxo1QL6J/2qTadyF3t9KnE9Eg==", + "dev": true + }, "@szmarczak/http-timer": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", diff --git a/package.json b/package.json index 0ff87b8a4..6a7518da5 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "./esm.mjs": "./esm.mjs", "./esm/transpile-only": "./esm/transpile-only.mjs", "./esm/transpile-only.mjs": "./esm/transpile-only.mjs", + "./transpilers/swc-experimental": "./transpilers/swc-experimental.js", "./node10/tsconfig.json": "./node10/tsconfig.json", "./node12/tsconfig.json": "./node12/tsconfig.json", "./node14/tsconfig.json": "./node14/tsconfig.json" @@ -36,6 +37,7 @@ "ts-node-transpile-only": "dist/bin-transpile.js" }, "files": [ + "transpilers/", "dist/", "dist-raw/", "register/", @@ -105,6 +107,8 @@ "timeout": "300s" }, "devDependencies": { + "@swc/core": ">=1.2.45", + "@swc/wasm": ">=1.2.45", "@types/chai": "^4.0.4", "@types/diff": "^4.0.2", "@types/lodash": "^4.14.151", @@ -134,8 +138,18 @@ "util.promisify": "^1.0.1" }, "peerDependencies": { + "@swc/core": ">=1.2.45", + "@swc/wasm": ">=1.2.45", "typescript": ">=2.7" }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + }, "dependencies": { "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", diff --git a/src/bin.ts b/src/bin.ts index 0924f96b0..f9378969f 100644 --- a/src/bin.ts +++ b/src/bin.ts @@ -41,6 +41,7 @@ export function main (argv: string[] = process.argv.slice(2), entrypointArgs: Re '--ignore-diagnostics': [String], '--ignore': [String], '--transpile-only': Boolean, + '--transpiler': String, '--type-check': Boolean, '--compiler-host': Boolean, '--pretty': Boolean, @@ -95,6 +96,7 @@ export function main (argv: string[] = process.argv.slice(2), entrypointArgs: Re '--ignore': ignore, '--transpile-only': transpileOnly, '--type-check': typeCheck, + '--transpiler': transpiler, '--compiler-host': compilerHost, '--pretty': pretty, '--skip-project': skipProject, @@ -120,11 +122,12 @@ export function main (argv: string[] = process.argv.slice(2), entrypointArgs: Re --cwd-mode Use current directory instead of for config resolution --show-config Print resolved configuration and exit - -T, --transpile-only Use TypeScript's faster \`transpileModule\` + -T, --transpile-only Use TypeScript's faster \`transpileModule\` or a third-party transpiler -H, --compiler-host Use TypeScript's compiler host API -I, --ignore [pattern] Override the path patterns to skip compilation -P, --project [path] Path to TypeScript JSON project file -C, --compiler [name] Specify a custom TypeScript compiler + --transpiler [name] Specify a third-party, non-typechecking transpiler -D, --ignore-diagnostics [code] Ignore TypeScript warnings by diagnostic code -O, --compiler-options [opts] JSON object to merge with compiler options @@ -159,8 +162,9 @@ export function main (argv: string[] = process.argv.slice(2), entrypointArgs: Re emit, files, pretty, - transpileOnly, + transpileOnly: transpileOnly ?? transpiler != null ? true : undefined, // tslint:disable-line:strict-type-predicates typeCheck, + transpiler, compilerHost, ignore, preferTsExts, diff --git a/src/index.spec.ts b/src/index.spec.ts index e6ea53eff..895c339bf 100644 --- a/src/index.spec.ts +++ b/src/index.spec.ts @@ -99,6 +99,8 @@ test.suite('ts-node', (test) => { testsDirRequire.resolve('ts-node/esm/transpile-only') testsDirRequire.resolve('ts-node/esm/transpile-only.mjs') + testsDirRequire.resolve('ts-node/transpilers/swc-experimental') + testsDirRequire.resolve('ts-node/node10/tsconfig.json') testsDirRequire.resolve('ts-node/node12/tsconfig.json') testsDirRequire.resolve('ts-node/node14/tsconfig.json') @@ -272,6 +274,18 @@ test.suite('ts-node', (test) => { expect(err.message).to.contain('error TS1003: Identifier expected') }) + test('should support third-party transpilers via --transpiler', async () => { + const { err, stdout } = await exec(`${cmdNoProject} --transpiler ts-node/transpilers/swc-experimental transpile-only-swc`) + expect(err).to.equal(null) + expect(stdout).to.contain('hello world') + }) + + test('should support third-party transpilers via tsconfig', async () => { + const { err, stdout } = await exec(`${cmdNoProject} transpile-only-swc-via-tsconfig`) + expect(err).to.equal(null) + expect(stdout).to.contain('hello world') + }) + test('should pipe into `ts-node` and evaluate', async () => { const execPromise = exec(cmd) execPromise.child.stdin!.end("console.log('hello')") diff --git a/src/index.ts b/src/index.ts index f9fb36593..32f2d3233 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,6 +7,7 @@ import { fileURLToPath } from 'url' import type * as _ts from 'typescript' import { Module, createRequire as nodeCreateRequire, createRequireFromPath as nodeCreateRequireFromPath } from 'module' import type _createRequire from 'create-require' +import { Transpiler, TranspilerFactory } from './transpilers/types' import { getDefaultTsconfigJsonForNodeVersion } from './tsconfigs' /** @internal */ @@ -132,6 +133,19 @@ export interface TSCommon { parseJsonConfigFileContent: typeof _ts.parseJsonConfigFileContent formatDiagnostics: typeof _ts.formatDiagnostics formatDiagnosticsWithColorAndContext: typeof _ts.formatDiagnosticsWithColorAndContext + + createDocumentRegistry: typeof _ts.createDocumentRegistry + JsxEmit: typeof _ts.JsxEmit + createModuleResolutionCache: typeof _ts.createModuleResolutionCache + resolveModuleName: typeof _ts.resolveModuleName + resolveModuleNameFromCache: typeof _ts.resolveModuleNameFromCache + resolveTypeReferenceDirective: typeof _ts.resolveTypeReferenceDirective + createIncrementalCompilerHost: typeof _ts.createIncrementalCompilerHost + createSourceFile: typeof _ts.createSourceFile + getDefaultLibFileName: typeof _ts.getDefaultLibFileName + createIncrementalProgram: typeof _ts.createIncrementalProgram + createEmitAndSemanticDiagnosticsBuilderProgram: typeof _ts.createEmitAndSemanticDiagnosticsBuilderProgram + libs?: string[] } @@ -156,6 +170,10 @@ export namespace TSInternal { } } +export interface TSCompilerFactory { + createTypescriptCompiler (options?: any): TSCommon +} + /** * Export the current version. */ @@ -237,6 +255,10 @@ export interface CreateOptions { * @default "typescript" */ compiler?: string + /** + * Specify a custom transpiler for use with transpileOnly + */ + transpiler?: string | [string, object] /** * Paths which should not be compiled. * @@ -568,6 +590,24 @@ export function create (rawOptions: CreateOptions = {}): Service { getCanonicalFileName: ts.sys.useCaseSensitiveFileNames ? x => x : x => x.toLowerCase() } + if (options.transpileOnly && typeof transformers === 'function') { + throw new TypeError('Transformers function is unavailable in "--transpile-only"') + } + let customTranspiler: Transpiler | undefined = undefined + if (options.transpiler) { + if (!transpileOnly) throw new Error('Custom transpiler can only be used when transpileOnly is enabled.') + const transpilerName = typeof options.transpiler === 'string' ? options.transpiler : options.transpiler[0] + const transpilerOptions = typeof options.transpiler === 'string' ? {} : options.transpiler[1] ?? {} + // TODO mimic fixed resolution logic from loadCompiler master + // TODO refactor into a more generic "resolve dep relative to project" helper + const transpilerPath = require.resolve(transpilerName, { paths: [cwd, __dirname] }) + const transpilerFactory: TranspilerFactory = require(transpilerPath).create + customTranspiler = transpilerFactory({ + service: { options, config }, + ...transpilerOptions + }) + } + // Install source map support and read from memory cache. sourceMapSupport.install({ environment: 'node', @@ -1022,17 +1062,20 @@ export function create (rawOptions: CreateOptions = {}): Service { } } } else { - if (typeof transformers === 'function') { - throw new TypeError('Transformers function is unavailable in "--transpile-only"') - } - getOutput = (code: string, fileName: string): SourceOutput => { - const result = ts.transpileModule(code, { - fileName, - compilerOptions: config.options, - reportDiagnostics: true, - transformers: transformers - }) + let result: _ts.TranspileOutput + if (customTranspiler) { + result = customTranspiler.transpile(code, { + fileName + }) + } else { + result = ts.transpileModule(code, { + fileName, + compilerOptions: config.options, + reportDiagnostics: true, + transformers: transformers as _ts.CustomTransformers | undefined + }) + } const diagnosticList = filterDiagnostics(result.diagnostics || [], ignoreDiagnostics) if (diagnosticList.length) reportTSError(diagnosticList) @@ -1285,12 +1328,12 @@ function filterRecognizedTsConfigTsNodeOptions (jsonObject: any): TsConfigOption const { compiler, compilerHost, compilerOptions, emit, files, ignore, ignoreDiagnostics, logError, preferTsExts, pretty, require, skipIgnore, - transpileOnly, typeCheck + transpileOnly, typeCheck, transpiler } = jsonObject as TsConfigOptions const filteredTsConfigOptions = { compiler, compilerHost, compilerOptions, emit, files, ignore, ignoreDiagnostics, logError, preferTsExts, pretty, require, skipIgnore, - transpileOnly, typeCheck + transpileOnly, typeCheck, transpiler } // Use the typechecker to make sure this implementation has the correct set of properties const catchExtraneousProps: keyof TsConfigOptions = null as any as keyof typeof filteredTsConfigOptions @@ -1308,10 +1351,11 @@ type SourceOutput = [string, string] */ function updateOutput (outputText: string, fileName: string, sourceMap: string, getExtension: (fileName: string) => string) { const base64Map = Buffer.from(updateSourceMap(sourceMap, fileName), 'utf8').toString('base64') - const sourceMapContent = `data:application/json;charset=utf-8;base64,${base64Map}` - const sourceMapLength = `${basename(fileName)}.map`.length + (getExtension(fileName).length - extname(fileName).length) - - return outputText.slice(0, -sourceMapLength) + sourceMapContent + const sourceMapContent = `//# sourceMappingURL=data:application/json;charset=utf-8;base64,${base64Map}` + // Expected form: `//# sourceMappingURL=foo.js.map` for input file foo.tsx + const sourceMapLength = /*//# sourceMappingURL=*/ 21 + /*foo.tsx*/ basename(fileName).length - /*.tsx*/ extname(fileName).length + /*.js*/ getExtension(fileName).length + /*.map*/ 4 + // Only rewrite if existing directive exists, to support compilers that do not append a sourcemap directive + return (outputText.slice(-sourceMapLength, -sourceMapLength + 21) === '//# sourceMappingURL=' ? outputText.slice(0, -sourceMapLength) : outputText) + sourceMapContent } /** @@ -1337,7 +1381,7 @@ function filterDiagnostics (diagnostics: readonly _ts.Diagnostic[], ignore: numb * * Reference: https://github.com/microsoft/TypeScript/blob/fcd9334f57d85b73dd66ad2d21c02e84822f4841/src/services/utilities.ts#L705-L731 */ -function getTokenAtPosition (ts: typeof _ts, sourceFile: _ts.SourceFile, position: number): _ts.Node { +function getTokenAtPosition (ts: TSCommon, sourceFile: _ts.SourceFile, position: number): _ts.Node { let current: _ts.Node = sourceFile outer: while (true) { diff --git a/src/transpilers/swc.ts b/src/transpilers/swc.ts new file mode 100644 index 000000000..220e8b03b --- /dev/null +++ b/src/transpilers/swc.ts @@ -0,0 +1,100 @@ +import type * as ts from 'typescript' +import type * as swcWasm from '@swc/wasm' +import type * as swcTypes from '@swc/core' +import { CreateTranspilerOptions, Transpiler } from './types' + +export interface SwcTranspilerOptions extends CreateTranspilerOptions { + /** + * swc compiler to use for compilation + * Set to '@swc/wasm' to use swc's WASM compiler + * Default: '@swc/core', falling back to '@swc/wasm' + */ + swc?: string | typeof swcWasm +} + +export function create (createOptions: SwcTranspilerOptions): Transpiler { + const { swc, service: { config } } = createOptions + + // Load swc compiler + let swcInstance: typeof swcWasm + if (typeof swc === 'string') { + swcInstance = require(swc) as typeof swcWasm + } else if (swc == null) { // tslint:disable-line + let swcResolved + try { + swcResolved = require.resolve('@swc/core') + } catch (e) { + try { + swcResolved = require.resolve('@swc/wasm') + } catch (e) { + throw new Error('swc compiler requires either @swc/core or @swc/wasm to be installed as dependencies') + } + } + swcInstance = require(swcResolved) as typeof swcWasm + } else { + swcInstance = swc + } + + // Prepare SWC options derived from typescript compiler options + const compilerOptions = config.options + const { esModuleInterop, sourceMap, importHelpers, experimentalDecorators, emitDecoratorMetadata, target, jsxFactory, jsxFragmentFactory } = compilerOptions + const nonTsxOptions = createSwcOptions(false) + const tsxOptions = createSwcOptions(true) + function createSwcOptions (isTsx: boolean): swcTypes.Options { + return { + sourceMaps: sourceMap, + // isModule: true, + module: { + type: 'commonjs', + noInterop: !esModuleInterop + }, + swcrc: false, + jsc: { + externalHelpers: importHelpers, + parser: { + syntax: 'typescript', + tsx: isTsx, + 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! + } + } + } + } + } + + const transpile: Transpiler['transpile'] = (input, transpileOptions) => { + const { fileName } = transpileOptions + const swcOptions = fileName.endsWith('.tsx') || fileName.endsWith('.jsx') ? tsxOptions : nonTsxOptions + const { code, map } = swcInstance.transformSync(input, { + ...swcOptions, + filename: fileName + }) + return { outputText: code, sourceMapText: map } + } + + return { + transpile + } +} + +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') diff --git a/src/transpilers/types.ts b/src/transpilers/types.ts new file mode 100644 index 000000000..295f67e8d --- /dev/null +++ b/src/transpilers/types.ts @@ -0,0 +1,32 @@ +import type * as ts from 'typescript' +import { Service } from '..' + +/** + * Third-party transpilers are implemented as a CommonJS module with a + * named export "create" + */ +export interface TranspilerModule { + create: TranspilerFactory +} +/** + * Called by ts-node to create a custom transpiler. + */ +export type TranspilerFactory = (options: CreateTranspilerOptions) => Transpiler +export interface CreateTranspilerOptions { + // TODO this is confusing because its only a partial Service. Rename? + service: Pick +} +export interface Transpiler { + // TODOs + // Create spec for returning diagnostics? Currently transpilers are allowed to + // throw an error but that's it. + transpile (input: string, options: TranspileOptions): TranspileOutput +} +export interface TranspileOptions { + fileName: string +} +export interface TranspileOutput { + outputText: string + diagnostics?: ts.Diagnostic[] + sourceMapText?: string +} diff --git a/tests/package.json b/tests/package.json index 26351d2b8..2c03119b3 100644 --- a/tests/package.json +++ b/tests/package.json @@ -1,5 +1,6 @@ { "dependencies": { - "ts-node": "file:ts-node-packed.tgz" + "ts-node": "file:ts-node-packed.tgz", + "@swc/core": "latest" } } diff --git a/tests/transpile-only-swc-via-tsconfig/index.ts b/tests/transpile-only-swc-via-tsconfig/index.ts new file mode 100644 index 000000000..bf54bf041 --- /dev/null +++ b/tests/transpile-only-swc-via-tsconfig/index.ts @@ -0,0 +1,4 @@ +// intentional type errors to check transpile-only ESM loader skips type checking +parseInt(1101, 2) +const x: number = 'hello world' +console.log(x) diff --git a/tests/transpile-only-swc-via-tsconfig/tsconfig.json b/tests/transpile-only-swc-via-tsconfig/tsconfig.json new file mode 100644 index 000000000..a0a168951 --- /dev/null +++ b/tests/transpile-only-swc-via-tsconfig/tsconfig.json @@ -0,0 +1,11 @@ +{ + "ts-node": { + "transpileOnly": true, + "transpiler": "ts-node/transpilers/swc-experimental" + }, + "compilerOptions": { + "module": "ESNext", + "allowJs": true, + "jsx": "react" + } +} diff --git a/tests/transpile-only-swc/index.ts b/tests/transpile-only-swc/index.ts new file mode 100644 index 000000000..bf54bf041 --- /dev/null +++ b/tests/transpile-only-swc/index.ts @@ -0,0 +1,4 @@ +// intentional type errors to check transpile-only ESM loader skips type checking +parseInt(1101, 2) +const x: number = 'hello world' +console.log(x) diff --git a/tests/transpile-only-swc/tsconfig.json b/tests/transpile-only-swc/tsconfig.json new file mode 100644 index 000000000..03e0c3c5d --- /dev/null +++ b/tests/transpile-only-swc/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "module": "ESNext", + "allowJs": true, + "jsx": "react" + } +} diff --git a/transpilers/swc-experimental.js b/transpilers/swc-experimental.js new file mode 100644 index 000000000..7cf79b13c --- /dev/null +++ b/transpilers/swc-experimental.js @@ -0,0 +1 @@ +module.exports = require('../dist/transpilers/swc')