Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose lineLengths from source map cache #48460

Closed
isaacs opened this issue Jun 14, 2023 · 1 comment · Fixed by #48461
Closed

Expose lineLengths from source map cache #48460

isaacs opened this issue Jun 14, 2023 · 1 comment · Fixed by #48461
Labels
feature request Issues that request new features to be added to Node.js.

Comments

@isaacs
Copy link
Contributor

isaacs commented Jun 14, 2023

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.

@isaacs isaacs added the feature request Issues that request new features to be added to Node.js. label Jun 14, 2023
isaacs added a commit to isaacs/node that referenced this issue Jun 14, 2023
isaacs added a commit to isaacs/node that referenced this issue Jun 15, 2023
@isaacs
Copy link
Contributor Author

isaacs commented Jun 15, 2023

Using NODE_V8_COVERAGE env also precludes doing any kind of filtering of coverage data, or otherwise using it in interesting ways. For example, specifying that a unit test should provide coverage only for a specific portion of the system under test.

isaacs added a commit to isaacs/node that referenced this issue Jun 15, 2023
isaacs added a commit to tapjs/processinfo that referenced this issue Jun 15, 2023
isaacs added a commit to isaacs/node that referenced this issue Jun 24, 2023
isaacs added a commit to isaacs/node that referenced this issue Jun 25, 2023
nodejs-github-bot pushed a commit that referenced this issue Jul 12, 2023
Fix: #48460
PR-URL: #48461
Fixes: #48460
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
juanarbol pushed a commit that referenced this issue Jul 13, 2023
Fix: #48460
PR-URL: #48461
Fixes: #48460
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Ceres6 pushed a commit to Ceres6/node that referenced this issue Aug 14, 2023
Fix: nodejs#48460
PR-URL: nodejs#48461
Fixes: nodejs#48460
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Ceres6 pushed a commit to Ceres6/node that referenced this issue Aug 14, 2023
Fix: nodejs#48460
PR-URL: nodejs#48461
Fixes: nodejs#48460
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
@avivkeller avivkeller moved this from Awaiting Triage to Done in Node.js feature requests Jun 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request Issues that request new features to be added to Node.js.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant