diff --git a/src/repl.ts b/src/repl.ts index ad399b850..e402f3df7 100644 --- a/src/repl.ts +++ b/src/repl.ts @@ -480,6 +480,8 @@ export function createEvalAwarePartialHost( return { readFile, fileExists }; } +const sourcemapCommentRe = /\/\/# ?sourceMappingURL=\S+[\s\r\n]*$/; + type AppendCompileAndEvalInputResult = | { containsTopLevelAwait: true; valuePromise: Promise } | { containsTopLevelAwait: false; value: any }; @@ -525,8 +527,23 @@ function appendCompileAndEvalInput(options: { output = adjustUseStrict(output); + // Note: REPL does not respect sourcemaps! + // To properly do that, we'd need to prefix the code we eval -- which comes + // from `diffLines` -- with newlines so that it's at the proper line numbers. + // Then we'd need to ensure each bit of eval-ed code, if there are multiples, + // has the sourcemap appended to it. + // We might also need to integrate with our sourcemap hooks' cache; I'm not sure. + const outputWithoutSourcemapComment = output.replace(sourcemapCommentRe, ''); + const oldOutputWithoutSourcemapComment = state.output.replace( + sourcemapCommentRe, + '' + ); + // Use `diff` to check for new JavaScript to execute. - const changes = diffLines(state.output, output); + const changes = diffLines( + oldOutputWithoutSourcemapComment, + outputWithoutSourcemapComment + ); if (isCompletion) { undo(); diff --git a/src/test/repl/repl.spec.ts b/src/test/repl/repl.spec.ts index 8e1ceab04..e838e5ae7 100644 --- a/src/test/repl/repl.spec.ts +++ b/src/test/repl/repl.spec.ts @@ -32,6 +32,16 @@ test('should run REPL when --interactive passed and stdin is not a TTY', async ( expect(stdout).toBe('> 123\n' + 'undefined\n' + '> '); }); +test('should echo a value when using the swc transpiler', async () => { + const execPromise = exec( + `${CMD_TS_NODE_WITH_PROJECT_FLAG} --interactive --transpiler ts-node/transpilers/swc-experimental` + ); + execPromise.child.stdin!.end('400\n401\n'); + const { err, stdout } = await execPromise; + expect(err).toBe(null); + expect(stdout).toBe('> 400\n>401\n > '); +}); + test('REPL has command to get type information', async () => { const execPromise = exec(`${CMD_TS_NODE_WITH_PROJECT_FLAG} --interactive`); execPromise.child.stdin!.end('\nconst a = 123\n.type a');