lib: allow skipping source maps in node_modules · nodejs/node@2fb007f · GitHub
Skip to content

Commit 2fb007f

Browse files
legendecasaduh95
authored andcommitted
lib: allow skipping source maps in node_modules
Files in `node_modules` are not authored by the user directly and the original sources are less relevant to the user. Skipping source maps in `node_modules` improves the general performance. Add `module.setSourceMapsSupport(enabled, options)` to skip source maps in `node_modules` if it is needed. This moves all source maps related API to `node:module` and this a step to promote the source maps API to stable. PR-URL: #56639 Reviewed-By: Vinícius Lourenço Claro Cardoso <contact@viniciusl.com.br> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent f885496 commit 2fb007f

24 files changed

Lines changed: 491 additions & 48 deletions

benchmark/es/error-stack.js

Lines changed: 22 additions & 4 deletions

benchmark/fixtures/node_modules/error-stack/simple-error-stack.js

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

benchmark/fixtures/node_modules/error-stack/simple-error-stack.ts

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

doc/api/module.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,6 +1590,20 @@ import { findSourceMap, SourceMap } from 'node:module';
15901590
const { findSourceMap, SourceMap } = require('node:module');
15911591
```
15921592
1593+
### `module.getSourceMapsSupport()`
1594+
1595+
<!-- YAML
1596+
added: REPLACEME
1597+
-->
1598+
1599+
* Returns: {Object}
1600+
* `enabled` {boolean} If the source maps support is enabled
1601+
* `nodeModules` {boolean} If the support is enabled for files in `node_modules`.
1602+
* `generatedCode` {boolean} If the support is enabled for generated code from `eval` or `new Function`.
1603+
1604+
This method returns whether the [Source Map v3][Source Map] support for stack
1605+
traces is enabled.
1606+
15931607
<!-- Anchors to make sure old links find a target -->
15941608
15951609
<a id="module_module_findsourcemap_path_error"></a>
@@ -1609,6 +1623,31 @@ added:
16091623
`path` is the resolved path for the file for which a corresponding source map
16101624
should be fetched.
16111625
1626+
### `module.setSourceMapsSupport(enabled[, options])`
1627+
1628+
<!-- YAML
1629+
added: REPLACEME
1630+
-->
1631+
1632+
* `enabled` {boolean} Enable the source map support.
1633+
* `options` {Object} Optional
1634+
* `nodeModules` {boolean} If enabling the support for files in
1635+
`node_modules`. **Default:** `false`.
1636+
* `generatedCode` {boolean} If enabling the support for generated code from
1637+
`eval` or `new Function`. **Default:** `false`.
1638+
1639+
This function enables or disables the [Source Map v3][Source Map] support for
1640+
stack traces.
1641+
1642+
It provides same features as launching Node.js process with commandline options
1643+
`--enable-source-maps`, with additional options to alter the support for files
1644+
in `node_modules` or generated codes.
1645+
1646+
Only source maps in JavaScript files that are loaded after source maps has been
1647+
enabled will be parsed and loaded. Preferably, use the commandline options
1648+
`--enable-source-maps` to avoid losing track of source maps of modules loaded
1649+
before this API call.
1650+
16121651
### Class: `module.SourceMap`
16131652
16141653
<!-- YAML
@@ -1709,6 +1748,7 @@ returned object contains the following keys:
17091748
[Customization hooks]: #customization-hooks
17101749
[ES Modules]: esm.md
17111750
[Permission Model]: permissions.md#permission-model
1751+
[Source Map]: https://sourcemaps.info/spec.html
17121752
[Source map v3 format]: https://sourcemaps.info/spec.html#h.mofvlxcwqzej
17131753
[V8 JavaScript code coverage]: https://v8project.blogspot.com/2017/12/javascript-code-coverage.html
17141754
[V8 code cache]: https://v8.dev/blog/code-caching-for-devs

doc/api/process.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3987,7 +3987,7 @@ added:
39873987
- v14.18.0
39883988
-->
39893989
3990-
> Stability: 1 - Experimental
3990+
> Stability: 1 - Experimental: Use [`module.setSourceMapsSupport()`][] instead.
39913991
39923992
* `val` {boolean}
39933993
@@ -4000,6 +4000,9 @@ It provides same features as launching Node.js process with commandline options
40004000
Only source maps in JavaScript files that are loaded after source maps has been
40014001
enabled will be parsed and loaded.
40024002
4003+
This implies calling `module.setSourceMapsSupport()` with an option
4004+
`{ nodeModules: true, generatedCode: true }`.
4005+
40034006
## `process.setUncaughtExceptionCaptureCallback(fn)`
40044007
40054008
<!-- YAML
@@ -4034,7 +4037,7 @@ added:
40344037
- v18.19.0
40354038
-->
40364039
4037-
> Stability: 1 - Experimental
4040+
> Stability: 1 - Experimental: Use [`module.getSourceMapsSupport()`][] instead.
40384041
40394042
* {boolean}
40404043
@@ -4501,7 +4504,9 @@ cases:
45014504
[`console.error()`]: console.md#consoleerrordata-args
45024505
[`console.log()`]: console.md#consolelogdata-args
45034506
[`domain`]: domain.md
4507+
[`module.getSourceMapsSupport()`]: module.md#modulegetsourcemapssupport
45044508
[`module.isBuiltin(id)`]: module.md#moduleisbuiltinmodulename
4509+
[`module.setSourceMapsSupport()`]: module.md#modulesetsourcemapssupportenabled-options
45054510
[`net.Server`]: net.md#class-netserver
45064511
[`net.Socket`]: net.md#class-netsocket
45074512
[`os.constants.dlopen`]: os.md#dlopen-constants

lib/internal/bootstrap/node.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -368,8 +368,8 @@ internalBinding('process_methods').setEmitWarningSync(emitWarningSync);
368368

369369
{
370370
const {
371-
getSourceMapsEnabled,
372-
setSourceMapsEnabled,
371+
getSourceMapsSupport,
372+
setSourceMapsSupport,
373373
maybeCacheGeneratedSourceMap,
374374
} = require('internal/source_map/source_map_cache');
375375
const {
@@ -381,10 +381,19 @@ internalBinding('process_methods').setEmitWarningSync(emitWarningSync);
381381
enumerable: true,
382382
configurable: true,
383383
get() {
384-
return getSourceMapsEnabled();
384+
return getSourceMapsSupport().enabled;
385385
},
386386
});
387-
process.setSourceMapsEnabled = setSourceMapsEnabled;
387+
process.setSourceMapsEnabled = function setSourceMapsEnabled(val) {
388+
setSourceMapsSupport(val, {
389+
__proto__: null,
390+
// TODO(legendecas): In order to smoothly improve the source map support,
391+
// skip source maps in node_modules and generated code with
392+
// `process.setSourceMapsEnabled(true)` in a semver major version.
393+
nodeModules: val,
394+
generatedCode: val,
395+
});
396+
};
388397
// The C++ land calls back to maybeCacheGeneratedSourceMap()
389398
// when code is generated by user with eval() or new Function()
390399
// to cache the source maps from the evaluated code, if any.

lib/internal/modules/esm/module_job.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const {
3030
} = internalBinding('util');
3131
const { decorateErrorStack, kEmptyObject } = require('internal/util');
3232
const {
33-
getSourceMapsEnabled,
33+
getSourceMapsSupport,
3434
} = require('internal/source_map/source_map_cache');
3535
const assert = require('internal/assert');
3636
const resolvedPromise = PromiseResolve();
@@ -186,7 +186,7 @@ class ModuleJob extends ModuleJobBase {
186186
// of missing named export. This is currently not possible because
187187
// stack trace originates in module_job, not the file itself. A hidden
188188
// symbol with filename could be set in node_errors.cc to facilitate this.
189-
if (!getSourceMapsEnabled() &&
189+
if (!getSourceMapsSupport().enabled &&
190190
StringPrototypeIncludes(e.message,
191191
' does not provide an export named')) {
192192
const splitStack = StringPrototypeSplit(e.stack, '\n');

lib/internal/process/pre_execution.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -608,9 +608,17 @@ function initializeESMLoader(forceDefaultLoader) {
608608

609609
function initializeSourceMapsHandlers() {
610610
const {
611-
setSourceMapsEnabled,
611+
setSourceMapsSupport,
612612
} = require('internal/source_map/source_map_cache');
613-
setSourceMapsEnabled(getOptionValue('--enable-source-maps'));
613+
const enabled = getOptionValue('--enable-source-maps');
614+
setSourceMapsSupport(enabled, {
615+
__proto__: null,
616+
// TODO(legendecas): In order to smoothly improve the source map support,
617+
// skip source maps in node_modules and generated code with
618+
// `--enable-source-maps` in a semver major version.
619+
nodeModules: enabled,
620+
generatedCode: enabled,
621+
});
614622
}
615623

616624
function initializeFrozenIntrinsics() {

lib/internal/source_map/source_map_cache.js

Lines changed: 46 additions & 19 deletions

0 commit comments

Comments
 (0)