-
-
Notifications
You must be signed in to change notification settings - Fork 33.1k
Description
What is the problem this feature will solve?
Currently, if a test framework (or any other kind of program) wants to do anything interesting with source maps or V8's built-in coverage APIs, they need to be able to get at the lineLengths
in order to map the byte offsets to line and column numbers in ergonomic coverage reports. (For example, c8 report
.)
When the generated and origin source filenames are different, this easy enough, by reading the actual generated file on disk.
However, when a module is compiled in-place (as with ts-node
or other transpiliers) the generated source code is never exposed anywhere. It's generated, passed to node, and then never exposed again.
The information is available when getting a SourceMap
object (since that's where it gets the SourceMap.payload from), but it's not exposed, and there's no reliable way to get it.
What is the feature you are proposing to solve the problem?
Add SourceMap.lineLengths
property, and set it in the constructor when the object is created from the cached source map data.
What alternatives have you considered?
- Using
NODE_V8_COVERAGE
env. - Reading the file directly to get lineLengths
- Inspect in
require.extensions
and/or--loader
load()
method
using NODE_V8_COVERAGE
env
When using NODE_V8_COVERAGE
, there is no option to limit what gets dumped into the coverage directory. As a result, in a typical node program, 99% or more of the test coverage data is irrelevant. Several projects of mine generate up to a GB of coverage data using this approach, only 100k or less of which is actually used in generating coverage reports, making these reports unnecessarily slow to generate and since I have hundreds of projects and am continually converting them to use built-in coverage instead of nyc, this data consumes a significant and growing amount of disk space for no benefit. Using the V8 coverage API directly, I'm able to produce the same reports using only around 5MB at most, even in fairly large projects.
Reading the file directly to get lineLengths
This doesn't work when the file is transpiled, because what you end up with is the origin line lengths, not the generated line lengths, which are what's actually required.
Inferring lineLengths from source map payload data
This is what I'm exploring currently. It's a lot of math, and Node already has the answer right there in memory, so it seems rather inelegant to be having to do this.
Nope. Not possible. Happy to share the proof if anyone's curious why this isn't an option.
Some kind of hack in require.extensions
or --loader
load()
method
It seems like it would b possible to get the generated source by means of hooking into require.extensions['.js'] for cjs, or inspecting the return value of nextLoad
in an esm loader hook. However, this is extremely brittle, and works if the loader is defined after any transpilers that might return generated code.