@@ -30,12 +30,18 @@ const {
30
30
normalizeReferrerURL,
31
31
} = require ( 'internal/modules/cjs/helpers' ) ;
32
32
const { validateBoolean } = require ( 'internal/validators' ) ;
33
+ const { setMaybeCacheGeneratedSourceMap } = internalBinding ( 'errors' ) ;
34
+
33
35
// Since the CJS module cache is mutable, which leads to memory leaks when
34
36
// modules are deleted, we use a WeakMap so that the source map cache will
35
37
// be purged automatically:
36
38
const cjsSourceMapCache = new IterableWeakMap ( ) ;
37
39
// The esm cache is not mutable, so we can use a Map without memory concerns:
38
40
const esmSourceMapCache = new SafeMap ( ) ;
41
+ // The generated sources is not mutable, so we can use a Map without memory concerns:
42
+ const generatedSourceMapCache = new SafeMap ( ) ;
43
+ const kLeadingProtocol = / ^ \w + : \/ \/ / ;
44
+
39
45
const { fileURLToPath, pathToFileURL, URL } = require ( 'internal/url' ) ;
40
46
let SourceMap ;
41
47
@@ -71,14 +77,13 @@ function setSourceMapsEnabled(val) {
71
77
sourceMapsEnabled = val ;
72
78
}
73
79
74
- function maybeCacheSourceMap ( filename , content , cjsModuleInstance ) {
80
+ function maybeCacheSourceMap ( filename , content , cjsModuleInstance , isGeneratedSource ) {
75
81
const sourceMapsEnabled = getSourceMapsEnabled ( ) ;
76
82
if ( ! ( process . env . NODE_V8_COVERAGE || sourceMapsEnabled ) ) return ;
77
83
try {
78
84
filename = normalizeReferrerURL ( filename ) ;
79
85
} catch ( err ) {
80
- // This is most likely an [eval]-wrapper, which is currently not
81
- // supported.
86
+ // This is most likely an invalid filename in sourceURL of [eval]-wrapper.
82
87
debug ( err ) ;
83
88
return ;
84
89
}
@@ -96,8 +101,14 @@ function maybeCacheSourceMap(filename, content, cjsModuleInstance) {
96
101
data,
97
102
url
98
103
} ) ;
104
+ } else if ( isGeneratedSource ) {
105
+ generatedSourceMapCache . set ( filename , {
106
+ lineLengths : lineLengths ( content ) ,
107
+ data,
108
+ url
109
+ } ) ;
99
110
} else {
100
- // If there is no cjsModuleInstance assume we are in a
111
+ // If there is no cjsModuleInstance and is not generated source assume we are in a
101
112
// "modules/esm" context.
102
113
esmSourceMapCache . set ( filename , {
103
114
lineLengths : lineLengths ( content ) ,
@@ -108,6 +119,31 @@ function maybeCacheSourceMap(filename, content, cjsModuleInstance) {
108
119
}
109
120
}
110
121
122
+ function maybeCacheGeneratedSourceMap ( content ) {
123
+ const sourceMapsEnabled = getSourceMapsEnabled ( ) ;
124
+ if ( ! ( process . env . NODE_V8_COVERAGE || sourceMapsEnabled ) ) return ;
125
+
126
+ const matchSourceURL = RegExpPrototypeExec (
127
+ / \/ [ * / ] # \s + s o u r c e U R L = (?< sourceURL > [ ^ \s ] + ) / ,
128
+ content
129
+ ) ;
130
+ if ( matchSourceURL == null ) {
131
+ return ;
132
+ }
133
+ let sourceURL = matchSourceURL . groups . sourceURL ;
134
+ if ( RegExpPrototypeExec ( kLeadingProtocol , sourceURL ) === null ) {
135
+ sourceURL = pathToFileURL ( sourceURL ) . href ;
136
+ }
137
+ try {
138
+ maybeCacheSourceMap ( sourceURL , content , null , true ) ;
139
+ } catch ( err ) {
140
+ // This can happen if the filename is not a valid URL.
141
+ // If we fail to cache the source map, we should not fail the whole process.
142
+ debug ( err ) ;
143
+ }
144
+ }
145
+ setMaybeCacheGeneratedSourceMap ( maybeCacheGeneratedSourceMap ) ;
146
+
111
147
function dataFromUrl ( sourceURL , sourceMappingURL ) {
112
148
try {
113
149
const url = new URL ( sourceMappingURL ) ;
@@ -218,21 +254,26 @@ function appendCJSCache(obj) {
218
254
}
219
255
}
220
256
221
- function findSourceMap ( sourceURL ) {
222
- if ( RegExpPrototypeExec ( / ^ \w + : \/ \/ / , sourceURL ) === null ) {
257
+ function findSourceMap ( sourceURL , isGenerated ) {
258
+ if ( RegExpPrototypeExec ( kLeadingProtocol , sourceURL ) === null ) {
223
259
sourceURL = pathToFileURL ( sourceURL ) . href ;
224
260
}
225
261
if ( ! SourceMap ) {
226
262
SourceMap = require ( 'internal/source_map/source_map' ) . SourceMap ;
227
263
}
228
- let sourceMap = esmSourceMapCache . get ( sourceURL ) ;
229
- if ( sourceMap === undefined ) {
230
- for ( const value of cjsSourceMapCache ) {
231
- const filename = ObjectGetValueSafe ( value , 'filename' ) ;
232
- if ( sourceURL === filename ) {
233
- sourceMap = {
234
- data : ObjectGetValueSafe ( value , 'data' )
235
- } ;
264
+ let sourceMap ;
265
+ if ( isGenerated ) {
266
+ sourceMap = generatedSourceMapCache . get ( sourceURL ) ;
267
+ } else {
268
+ sourceMap = esmSourceMapCache . get ( sourceURL ) ;
269
+ if ( sourceMap === undefined ) {
270
+ for ( const value of cjsSourceMapCache ) {
271
+ const filename = ObjectGetValueSafe ( value , 'filename' ) ;
272
+ if ( sourceURL === filename ) {
273
+ sourceMap = {
274
+ data : ObjectGetValueSafe ( value , 'data' )
275
+ } ;
276
+ }
236
277
}
237
278
}
238
279
}
0 commit comments