ts-node icon indicating copy to clipboard operation
ts-node copied to clipboard

Expose Compiled Output via API

Open dsanders11 opened this issue 5 years ago • 3 comments

Desired Behavior

I'd like to be able to access the compiled output for a filename. I think this could be accomplished well by adding a getCompiledOutput(filename) to the return value for create().

Is this request related to a problem?

I have a use-case where I'd like to go from the Function.prototype.toString() to the original source code, and the best way to do that is find the line numbers in the compiled output, then use those to look up the original positions in the source map.

Alternatives you've considered

I currently get around this by wrapping the compiler to save off the output myself before it is returned to ts-node, but that's a bit fragile. It relies on me keeping it up-to-date with the API of the compiler, and if caching comes back into ts-node at some point then it might not call the compiler for a file if it's cached.

Additional context

The information is all there in outputCache, it's just a matter of exposing it, most likely in a way that is immutable to prevent quirks.

dsanders11 avatar Nov 26 '20 06:11 dsanders11

If you want to do source-mapping, we already install source-map-support, a third-party library which rewrites stack traces based on sourcemaps. I wonder if it exposes an API you can use to map from .js to .ts positions.

cspotcode avatar Nov 26 '20 07:11 cspotcode

@cspotcode, yea, I'm already using that functionality. Since source map libraries are aimed at mapping mostly just line/column numbers back to the source, they don't readily support getting the raw transformed source that the map is for. I need the transformed source since Function.prototype.toString() (by spec, apparently) is the exact source executed by the runtime, so it will be the transformed source, and there's no metadata about line numbers.

Here's psuedo-code of what I'm currently doing:

const { SourceMapConsumer } = require("source-map");
const { retrieveSourceMap } = require("source-map-support");

const urlAndMap = retrieveSourceMap(file);
const sourceMap = new SourceMapConsumer(urlAndMap.map);

const transformedContent = getFileContent(file); // What I need support for

const targetText = someFunction.toString();
const { line, column } = findTargetText(transformedContent, targetText);
// Find index in `transformedContent` for the code we're interested in
const originalPosition = sourceMap.originalPositionFor({ line, column });

I considered making the issue on source-map-support instead of this repo, but I have a feeling they might consider getting the transformed content to be out-of-scope and not want to include it. It's less out-of-scope on this repo, and there may be other reasons one wants to get the compiled output beyond my use-case.

EDIT: Also, if the underlying library used for source maps changes, I'd be back to square one. I know there was discussion from you about supporting Node's built-in source map support, so in that situation someone would be back to square one in needing to get the compiled output.

dsanders11 avatar Nov 26 '20 07:11 dsanders11

Marking "help wanted" to indicate we'll wait for a pull request for this.

cspotcode avatar Sep 19 '21 17:09 cspotcode