| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent c78e110 commit d5bf3db
24 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,13 +2,19 @@ | |||
| 2 | 2 | ||
| 3 | 3 | const common = require('../common.js'); | |
| 4 | 4 | const modPath = require.resolve('../fixtures/simple-error-stack.js'); | |
| 5 | + const nodeModulePath = require.resolve('../fixtures/node_modules/error-stack/simple-error-stack.js'); | ||
| 6 | + const Module = require('node:module'); | ||
| 5 | 7 | ||
| 6 | 8 | const bench = common.createBenchmark(main, { | |
| 7 | - method: ['without-sourcemap', 'sourcemap'], | ||
| 9 | + method: [ | ||
| 10 | + 'without-sourcemap', | ||
| 11 | + 'sourcemap', | ||
| 12 | + 'node-modules-without-sourcemap', | ||
| 13 | + 'node-module-sourcemap'], | ||
| 8 | 14 | n: [1e5], | |
| 9 | 15 | }); | |
| 10 | 16 | ||
| 11 | - function runN(n) { | ||
| 17 | + function runN(n, modPath) { | ||
| 12 | 18 | delete require.cache[modPath]; | |
| 13 | 19 | const mod = require(modPath); | |
| 14 | 20 | bench.start(); | |
@@ -22,11 +28,23 @@ function main({ n, method }) { | |||
| 22 | 28 | switch (method) { | |
| 23 | 29 | case 'without-sourcemap': | |
| 24 | 30 | process.setSourceMapsEnabled(false); | |
| 25 | - runN(n); | ||
| 31 | + runN(n, modPath); | ||
| 26 | 32 | break; | |
| 27 | 33 | case 'sourcemap': | |
| 28 | 34 | process.setSourceMapsEnabled(true); | |
| 29 | - runN(n); | ||
| 35 | + runN(n, modPath); | ||
| 36 | + break; | ||
| 37 | + case 'node-modules-without-sourcemap': | ||
| 38 | + Module.setSourceMapsSupport(true, { | ||
| 39 | + nodeModules: false, | ||
| 40 | + }); | ||
| 41 | + runN(n, nodeModulePath); | ||
| 42 | + break; | ||
| 43 | + case 'node-modules-sourcemap': | ||
| 44 | + Module.setSourceMapsSupport(true, { | ||
| 45 | + nodeModules: true, | ||
| 46 | + }); | ||
| 47 | + runN(n, nodeModulePath); | ||
| 30 | 48 | break; | |
| 31 | 49 | default: | |
| 32 | 50 | throw new Error(`Unexpected method "${method}"`); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1446,6 +1446,20 @@ import { findSourceMap, SourceMap } from 'node:module'; | |||
| 1446 | 1446 | const { findSourceMap, SourceMap } = require('node:module'); | |
| 1447 | 1447 | ``` | |
| 1448 | 1448 | ||
| 1449 | + ### `module.getSourceMapsSupport()` | ||
| 1450 | + | ||
| 1451 | + <!-- YAML | ||
| 1452 | + added: REPLACEME | ||
| 1453 | + --> | ||
| 1454 | + | ||
| 1455 | + * Returns: {Object} | ||
| 1456 | + * `enabled` {boolean} If the source maps support is enabled | ||
| 1457 | + * `nodeModules` {boolean} If the support is enabled for files in `node_modules`. | ||
| 1458 | + * `generatedCode` {boolean} If the support is enabled for generated code from `eval` or `new Function`. | ||
| 1459 | + | ||
| 1460 | + This method returns whether the [Source Map v3][Source Map] support for stack | ||
| 1461 | + traces is enabled. | ||
| 1462 | + | ||
| 1449 | 1463 | <!-- Anchors to make sure old links find a target --> | |
| 1450 | 1464 | ||
| 1451 | 1465 | <a id="module_module_findsourcemap_path_error"></a> | |
@@ -1465,6 +1479,31 @@ added: | |||
| 1465 | 1479 | `path` is the resolved path for the file for which a corresponding source map | |
| 1466 | 1480 | should be fetched. | |
| 1467 | 1481 | ||
| 1482 | + ### `module.setSourceMapsSupport(enabled[, options])` | ||
| 1483 | + | ||
| 1484 | + <!-- YAML | ||
| 1485 | + added: REPLACEME | ||
| 1486 | + --> | ||
| 1487 | + | ||
| 1488 | + * `enabled` {boolean} Enable the source map support. | ||
| 1489 | + * `options` {Object} Optional | ||
| 1490 | + * `nodeModules` {boolean} If enabling the support for files in | ||
| 1491 | + `node_modules`. **Default:** `false`. | ||
| 1492 | + * `generatedCode` {boolean} If enabling the support for generated code from | ||
| 1493 | + `eval` or `new Function`. **Default:** `false`. | ||
| 1494 | + | ||
| 1495 | + This function enables or disables the [Source Map v3][Source Map] support for | ||
| 1496 | + stack traces. | ||
| 1497 | + | ||
| 1498 | + It provides same features as launching Node.js process with commandline options | ||
| 1499 | + `--enable-source-maps`, with additional options to alter the support for files | ||
| 1500 | + in `node_modules` or generated codes. | ||
| 1501 | + | ||
| 1502 | + Only source maps in JavaScript files that are loaded after source maps has been | ||
| 1503 | + enabled will be parsed and loaded. Preferably, use the commandline options | ||
| 1504 | + `--enable-source-maps` to avoid losing track of source maps of modules loaded | ||
| 1505 | + before this API call. | ||
| 1506 | + | ||
| 1468 | 1507 | ### Class: `module.SourceMap` | |
| 1469 | 1508 | ||
| 1470 | 1509 | <!-- YAML | |
@@ -1565,6 +1604,7 @@ returned object contains the following keys: | |||
| 1565 | 1604 | [Customization hooks]: #customization-hooks | |
| 1566 | 1605 | [ES Modules]: esm.md | |
| 1567 | 1606 | [Permission Model]: permissions.md#permission-model | |
| 1607 | + [Source Map]: https://sourcemaps.info/spec.html | ||
| 1568 | 1608 | [Source map v3 format]: https://sourcemaps.info/spec.html#h.mofvlxcwqzej | |
| 1569 | 1609 | [V8 JavaScript code coverage]: https://v8project.blogspot.com/2017/12/javascript-code-coverage.html | |
| 1570 | 1610 | [V8 code cache]: https://v8.dev/blog/code-caching-for-devs | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3974,7 +3974,7 @@ added: | |||
| 3974 | 3974 | - v14.18.0 | |
| 3975 | 3975 | --> | |
| 3976 | 3976 | ||
| 3977 | - > Stability: 1 - Experimental | ||
| 3977 | + > Stability: 1 - Experimental: Use [`module.setSourceMapsSupport()`][] instead. | ||
| 3978 | 3978 | ||
| 3979 | 3979 | * `val` {boolean} | |
| 3980 | 3980 | ||
@@ -3987,6 +3987,9 @@ It provides same features as launching Node.js process with commandline options | |||
| 3987 | 3987 | Only source maps in JavaScript files that are loaded after source maps has been | |
| 3988 | 3988 | enabled will be parsed and loaded. | |
| 3989 | 3989 | ||
| 3990 | + This implies calling `module.setSourceMapsSupport()` with an option | ||
| 3991 | + `{ nodeModules: true, generatedCode: true }`. | ||
| 3992 | + | ||
| 3990 | 3993 | ## `process.setUncaughtExceptionCaptureCallback(fn)` | |
| 3991 | 3994 | ||
| 3992 | 3995 | <!-- YAML | |
@@ -4021,7 +4024,7 @@ added: | |||
| 4021 | 4024 | - v18.19.0 | |
| 4022 | 4025 | --> | |
| 4023 | 4026 | ||
| 4024 | - > Stability: 1 - Experimental | ||
| 4027 | + > Stability: 1 - Experimental: Use [`module.getSourceMapsSupport()`][] instead. | ||
| 4025 | 4028 | ||
| 4026 | 4029 | * {boolean} | |
| 4027 | 4030 | ||
@@ -4488,7 +4491,9 @@ cases: | |||
| 4488 | 4491 | [`console.error()`]: console.md#consoleerrordata-args | |
| 4489 | 4492 | [`console.log()`]: console.md#consolelogdata-args | |
| 4490 | 4493 | [`domain`]: domain.md | |
| 4494 | + [`module.getSourceMapsSupport()`]: module.md#modulegetsourcemapssupport | ||
| 4491 | 4495 | [`module.isBuiltin(id)`]: module.md#moduleisbuiltinmodulename | |
| 4496 | + [`module.setSourceMapsSupport()`]: module.md#modulesetsourcemapssupportenabled-options | ||
| 4492 | 4497 | [`net.Server`]: net.md#class-netserver | |
| 4493 | 4498 | [`net.Socket`]: net.md#class-netsocket | |
| 4494 | 4499 | [`os.constants.dlopen`]: os.md#dlopen-constants | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -377,8 +377,8 @@ internalBinding('process_methods').setEmitWarningSync(emitWarningSync); | |||
| 377 | 377 | ||
| 378 | 378 | { | |
| 379 | 379 | const { | |
| 380 | - getSourceMapsEnabled, | ||
| 381 | - setSourceMapsEnabled, | ||
| 380 | + getSourceMapsSupport, | ||
| 381 | + setSourceMapsSupport, | ||
| 382 | 382 | maybeCacheGeneratedSourceMap, | |
| 383 | 383 | } = require('internal/source_map/source_map_cache'); | |
| 384 | 384 | const { | |
@@ -390,10 +390,19 @@ internalBinding('process_methods').setEmitWarningSync(emitWarningSync); | |||
| 390 | 390 | enumerable: true, | |
| 391 | 391 | configurable: true, | |
| 392 | 392 | get() { | |
| 393 | - return getSourceMapsEnabled(); | ||
| 393 | + return getSourceMapsSupport().enabled; | ||
| 394 | 394 | }, | |
| 395 | 395 | }); | |
| 396 | - process.setSourceMapsEnabled = setSourceMapsEnabled; | ||
| 396 | + process.setSourceMapsEnabled = function setSourceMapsEnabled(val) { | ||
| 397 | + setSourceMapsSupport(val, { | ||
| 398 | + __proto__: null, | ||
| 399 | + // TODO(legendecas): In order to smoothly improve the source map support, | ||
| 400 | + // skip source maps in node_modules and generated code with | ||
| 401 | + // `process.setSourceMapsEnabled(true)` in a semver major version. | ||
| 402 | + nodeModules: val, | ||
| 403 | + generatedCode: val, | ||
| 404 | + }); | ||
| 405 | + }; | ||
| 397 | 406 | // The C++ land calls back to maybeCacheGeneratedSourceMap() | |
| 398 | 407 | // when code is generated by user with eval() or new Function() | |
| 399 | 408 | // to cache the source maps from the evaluated code, if any. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -30,7 +30,7 @@ const { | |||
| 30 | 30 | } = internalBinding('util'); | |
| 31 | 31 | const { decorateErrorStack, kEmptyObject } = require('internal/util'); | |
| 32 | 32 | const { | |
| 33 | - getSourceMapsEnabled, | ||
| 33 | + getSourceMapsSupport, | ||
| 34 | 34 | } = require('internal/source_map/source_map_cache'); | |
| 35 | 35 | const assert = require('internal/assert'); | |
| 36 | 36 | const resolvedPromise = PromiseResolve(); | |
@@ -185,7 +185,7 @@ class ModuleJob extends ModuleJobBase { | |||
| 185 | 185 | // of missing named export. This is currently not possible because | |
| 186 | 186 | // stack trace originates in module_job, not the file itself. A hidden | |
| 187 | 187 | // symbol with filename could be set in node_errors.cc to facilitate this. | |
| 188 | - if (!getSourceMapsEnabled() && | ||
| 188 | + if (!getSourceMapsSupport().enabled && | ||
| 189 | 189 | StringPrototypeIncludes(e.message, | |
| 190 | 190 | ' does not provide an export named')) { | |
| 191 | 191 | const splitStack = StringPrototypeSplit(e.stack, '\n'); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -698,9 +698,17 @@ function initializeESMLoader(forceDefaultLoader) { | |||
| 698 | 698 | ||
| 699 | 699 | function initializeSourceMapsHandlers() { | |
| 700 | 700 | const { | |
| 701 | - setSourceMapsEnabled, | ||
| 701 | + setSourceMapsSupport, | ||
| 702 | 702 | } = require('internal/source_map/source_map_cache'); | |
| 703 | - setSourceMapsEnabled(getOptionValue('--enable-source-maps')); | ||
| 703 | + const enabled = getOptionValue('--enable-source-maps'); | ||
| 704 | + setSourceMapsSupport(enabled, { | ||
| 705 | + __proto__: null, | ||
| 706 | + // TODO(legendecas): In order to smoothly improve the source map support, | ||
| 707 | + // skip source maps in node_modules and generated code with | ||
| 708 | + // `--enable-source-maps` in a semver major version. | ||
| 709 | + nodeModules: enabled, | ||
| 710 | + generatedCode: enabled, | ||
| 711 | + }); | ||
| 704 | 712 | } | |
| 705 | 713 | ||
| 706 | 714 | function initializeFrozenIntrinsics() { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,6 +3,7 @@ | |||
| 3 | 3 | const { | |
| 4 | 4 | ArrayPrototypePush, | |
| 5 | 5 | JSONParse, | |
| 6 | + ObjectFreeze, | ||
| 6 | 7 | RegExpPrototypeExec, | |
| 7 | 8 | SafeMap, | |
| 8 | 9 | StringPrototypeCodePointAt, | |
@@ -15,15 +16,15 @@ let debug = require('internal/util/debuglog').debuglog('source_map', (fn) => { | |||
| 15 | 16 | debug = fn; | |
| 16 | 17 | }); | |
| 17 | 18 | ||
| 18 | - const { validateBoolean } = require('internal/validators'); | ||
| 19 | + const { validateBoolean, validateObject } = require('internal/validators'); | ||
| 19 | 20 | const { | |
| 20 | 21 | setSourceMapsEnabled: setSourceMapsNative, | |
| 21 | 22 | } = internalBinding('errors'); | |
| 22 | 23 | const { | |
| 23 | 24 | defaultPrepareStackTrace, | |
| 24 | 25 | setInternalPrepareStackTrace, | |
| 25 | 26 | } = require('internal/errors'); | |
| 26 | - const { getLazy } = require('internal/util'); | ||
| 27 | + const { getLazy, isUnderNodeModules, kEmptyObject } = require('internal/util'); | ||
| 27 | 28 | ||
| 28 | 29 | const getModuleSourceMapCache = getLazy(() => { | |
| 29 | 30 | const { SourceMapCacheMap } = require('internal/source_map/source_map_cache_map'); | |
@@ -45,30 +46,48 @@ const { fileURLToPath, pathToFileURL, URL, URLParse } = require('internal/url'); | |||
| 45 | 46 | let SourceMap; | |
| 46 | 47 | ||
| 47 | 48 | // This is configured with --enable-source-maps during pre-execution. | |
| 48 | - let sourceMapsEnabled = false; | ||
| 49 | - function getSourceMapsEnabled() { | ||
| 50 | - return sourceMapsEnabled; | ||
| 49 | + let sourceMapsSupport = ObjectFreeze({ | ||
| 50 | + __proto__: null, | ||
| 51 | + enabled: false, | ||
| 52 | + nodeModules: false, | ||
| 53 | + generatedCode: false, | ||
| 54 | + }); | ||
| 55 | + function getSourceMapsSupport() { | ||
| 56 | + // Return a read-only object. | ||
| 57 | + return sourceMapsSupport; | ||
| 51 | 58 | } | |
| 52 | 59 | ||
| 53 | 60 | /** | |
| 54 | 61 | * Enables or disables source maps programmatically. | |
| 55 | - * @param {boolean} val | ||
| 62 | + * @param {boolean} enabled | ||
| 63 | + * @param {object} options | ||
| 64 | + * @param {boolean} [options.nodeModules] | ||
| 65 | + * @param {boolean} [options.generatedCode] | ||
| 56 | 66 | */ | |
| 57 | - function setSourceMapsEnabled(val) { | ||
| 58 | - validateBoolean(val, 'val'); | ||
| 67 | + function setSourceMapsSupport(enabled, options = kEmptyObject) { | ||
| 68 | + validateBoolean(enabled, 'enabled'); | ||
| 69 | + validateObject(options, 'options'); | ||
| 70 | + | ||
| 71 | + const { nodeModules = false, generatedCode = false } = options; | ||
| 72 | + validateBoolean(nodeModules, 'options.nodeModules'); | ||
| 73 | + validateBoolean(generatedCode, 'options.generatedCode'); | ||
| 59 | 74 | ||
| 60 | - setSourceMapsNative(val); | ||
| 61 | - if (val) { | ||
| 75 | + setSourceMapsNative(enabled); | ||
| 76 | + if (enabled) { | ||
| 62 | 77 | const { | |
| 63 | 78 | prepareStackTraceWithSourceMaps, | |
| 64 | 79 | } = require('internal/source_map/prepare_stack_trace'); | |
| 65 | 80 | setInternalPrepareStackTrace(prepareStackTraceWithSourceMaps); | |
| 66 | - } else if (sourceMapsEnabled !== undefined) { | ||
| 67 | - // Reset prepare stack trace callback only when disabling source maps. | ||
| 81 | + } else { | ||
| 68 | 82 | setInternalPrepareStackTrace(defaultPrepareStackTrace); | |
| 69 | 83 | } | |
| 70 | 84 | ||
| 71 | - sourceMapsEnabled = val; | ||
| 85 | + sourceMapsSupport = ObjectFreeze({ | ||
| 86 | + __proto__: null, | ||
| 87 | + enabled, | ||
| 88 | + nodeModules: nodeModules, | ||
| 89 | + generatedCode: generatedCode, | ||
| 90 | + }); | ||
| 72 | 91 | } | |
| 73 | 92 | ||
| 74 | 93 | /** | |
@@ -130,14 +149,18 @@ function extractSourceMapURLMagicComment(content) { | |||
| 130 | 149 | * @param {string | undefined} sourceMapURL - the source map url | |
| 131 | 150 | */ | |
| 132 | 151 | function maybeCacheSourceMap(filename, content, moduleInstance, isGeneratedSource, sourceURL, sourceMapURL) { | |
| 133 | - const sourceMapsEnabled = getSourceMapsEnabled(); | ||
| 134 | - if (!(process.env.NODE_V8_COVERAGE || sourceMapsEnabled)) return; | ||
| 152 | + const support = getSourceMapsSupport(); | ||
| 153 | + if (!(process.env.NODE_V8_COVERAGE || support.enabled)) return; | ||
| 135 | 154 | const { normalizeReferrerURL } = require('internal/modules/helpers'); | |
| 136 | 155 | filename = normalizeReferrerURL(filename); | |
| 137 | 156 | if (filename === undefined) { | |
| 138 | 157 | // This is most likely an invalid filename in sourceURL of [eval]-wrapper. | |
| 139 | 158 | return; | |
| 140 | 159 | } | |
| 160 | + if (!support.nodeModules && isUnderNodeModules(filename)) { | ||
| 161 | + // Skip file under node_modules if not enabled. | ||
| 162 | + return; | ||
| 163 | + } | ||
| 141 | 164 | ||
| 142 | 165 | if (sourceMapURL === undefined) { | |
| 143 | 166 | sourceMapURL = extractSourceMapURLMagicComment(content); | |
@@ -185,8 +208,8 @@ function maybeCacheSourceMap(filename, content, moduleInstance, isGeneratedSourc | |||
| 185 | 208 | * @param {string} content - the eval'd source code | |
| 186 | 209 | */ | |
| 187 | 210 | function maybeCacheGeneratedSourceMap(content) { | |
| 188 | - const sourceMapsEnabled = getSourceMapsEnabled(); | ||
| 189 | - if (!(process.env.NODE_V8_COVERAGE || sourceMapsEnabled)) return; | ||
| 211 | + const support = getSourceMapsSupport(); | ||
| 212 | + if (!(process.env.NODE_V8_COVERAGE || support.enabled || support.generated)) return; | ||
| 190 | 213 | ||
| 191 | 214 | const sourceURL = extractSourceURLMagicComment(content); | |
| 192 | 215 | if (sourceURL === null) { | |
@@ -352,6 +375,10 @@ function findSourceMap(sourceURL) { | |||
| 352 | 375 | return undefined; | |
| 353 | 376 | } | |
| 354 | 377 | ||
| 378 | + if (!getSourceMapsSupport().nodeModules && isUnderNodeModules(sourceURL)) { | ||
| 379 | + return undefined; | ||
| 380 | + } | ||
| 381 | + | ||
| 355 | 382 | SourceMap ??= require('internal/source_map/source_map').SourceMap; | |
| 356 | 383 | try { | |
| 357 | 384 | if (RegExpPrototypeExec(kLeadingProtocol, sourceURL) === null) { | |
@@ -377,8 +404,8 @@ function findSourceMap(sourceURL) { | |||
| 377 | 404 | ||
| 378 | 405 | module.exports = { | |
| 379 | 406 | findSourceMap, | |
| 380 | - getSourceMapsEnabled, | ||
| 381 | - setSourceMapsEnabled, | ||
| 407 | + getSourceMapsSupport, | ||
| 408 | + setSourceMapsSupport, | ||
| 382 | 409 | maybeCacheSourceMap, | |
| 383 | 410 | maybeCacheGeneratedSourceMap, | |
| 384 | 411 | sourceMapCacheToObject, | |
| Back | FazBrowse Home | New Git URL |
0 commit comments