77 ObjectKeys,
88 ObjectGetOwnPropertyDescriptor,
99 ObjectPrototypeHasOwnProperty,
10- RegExpPrototypeTest ,
10+ RegExpPrototypeExec ,
1111 SafeMap,
12- StringPrototypeMatch,
1312 StringPrototypeSplit,
1413} = primordials ;
1514
@@ -30,12 +29,18 @@ const {
3029 normalizeReferrerURL,
3130} = require ( 'internal/modules/cjs/helpers' ) ;
3231const { validateBoolean } = require ( 'internal/validators' ) ;
32+ const { setMaybeCacheGeneratedSourceMap } = internalBinding ( 'errors' ) ;
33+
3334// Since the CJS module cache is mutable, which leads to memory leaks when
3435// modules are deleted, we use a WeakMap so that the source map cache will
3536// be purged automatically:
3637const cjsSourceMapCache = new IterableWeakMap ( ) ;
3738// The esm cache is not mutable, so we can use a Map without memory concerns:
3839const esmSourceMapCache = new SafeMap ( ) ;
40+ // The generated sources is not mutable, so we can use a Map without memory concerns:
41+ const generatedSourceMapCache = new SafeMap ( ) ;
42+ const kLeadingProtocol = / ^ \w + : \/ \/ / ;
43+
3944const { fileURLToPath, pathToFileURL, URL } = require ( 'internal/url' ) ;
4045let SourceMap ;
4146
@@ -71,20 +76,19 @@ function setSourceMapsEnabled(val) {
7176 sourceMapsEnabled = val ;
7277}
7378
74- function maybeCacheSourceMap ( filename , content , cjsModuleInstance ) {
79+ function maybeCacheSourceMap ( filename , content , cjsModuleInstance , isGeneratedSource ) {
7580 const sourceMapsEnabled = getSourceMapsEnabled ( ) ;
7681 if ( ! ( process . env . NODE_V8_COVERAGE || sourceMapsEnabled ) ) return ;
7782 try {
7883 filename = normalizeReferrerURL ( filename ) ;
7984 } catch ( err ) {
80- // This is most likely an [eval]-wrapper, which is currently not
81- // supported.
85+ // This is most likely an invalid filename in sourceURL of [eval]-wrapper.
8286 debug ( err ) ;
8387 return ;
8488 }
85- const match = StringPrototypeMatch (
86- content ,
87- / \/ [ * / ] # \s + s o u r c e M a p p i n g U R L = (?< sourceMappingURL > [ ^ \s ] + ) /
89+ const match = RegExpPrototypeExec (
90+ / \/ [ * / ] # \s + s o u r c e M a p p i n g U R L = (?< sourceMappingURL > [ ^ \s ] + ) / ,
91+ content
8892 ) ;
8993 if ( match ) {
9094 const data = dataFromUrl ( filename , match . groups . sourceMappingURL ) ;
@@ -96,8 +100,14 @@ function maybeCacheSourceMap(filename, content, cjsModuleInstance) {
96100 data,
97101 url
98102 } ) ;
103+ } else if ( isGeneratedSource ) {
104+ generatedSourceMapCache . set ( filename , {
105+ lineLengths : lineLengths ( content ) ,
106+ data,
107+ url
108+ } ) ;
99109 } else {
100- // If there is no cjsModuleInstance assume we are in a
110+ // If there is no cjsModuleInstance and is not generated source assume we are in a
101111 // "modules/esm" context.
102112 esmSourceMapCache . set ( filename , {
103113 lineLengths : lineLengths ( content ) ,
@@ -108,6 +118,31 @@ function maybeCacheSourceMap(filename, content, cjsModuleInstance) {
108118 }
109119}
110120
121+ function maybeCacheGeneratedSourceMap ( content ) {
122+ const sourceMapsEnabled = getSourceMapsEnabled ( ) ;
123+ if ( ! ( process . env . NODE_V8_COVERAGE || sourceMapsEnabled ) ) return ;
124+
125+ const matchSourceURL = RegExpPrototypeExec (
126+ / \/ [ * / ] # \s + s o u r c e U R L = (?< sourceURL > [ ^ \s ] + ) / ,
127+ content
128+ ) ;
129+ if ( matchSourceURL == null ) {
130+ return ;
131+ }
132+ let sourceURL = matchSourceURL . groups . sourceURL ;
133+ if ( RegExpPrototypeExec ( kLeadingProtocol , sourceURL ) === null ) {
134+ sourceURL = pathToFileURL ( sourceURL ) . href ;
135+ }
136+ try {
137+ maybeCacheSourceMap ( sourceURL , content , null , true ) ;
138+ } catch ( err ) {
139+ // This can happen if the filename is not a valid URL.
140+ // If we fail to cache the source map, we should not fail the whole process.
141+ debug ( err ) ;
142+ }
143+ }
144+ setMaybeCacheGeneratedSourceMap ( maybeCacheGeneratedSourceMap ) ;
145+
111146function dataFromUrl ( sourceURL , sourceMappingURL ) {
112147 try {
113148 const url = new URL ( sourceMappingURL ) ;
@@ -218,21 +253,26 @@ function appendCJSCache(obj) {
218253 }
219254}
220255
221- function findSourceMap ( sourceURL ) {
222- if ( ! RegExpPrototypeTest ( / ^ \w + : \/ \/ / , sourceURL ) ) {
256+ function findSourceMap ( sourceURL , isGenerated ) {
257+ if ( RegExpPrototypeExec ( kLeadingProtocol , sourceURL ) === null ) {
223258 sourceURL = pathToFileURL ( sourceURL ) . href ;
224259 }
225260 if ( ! SourceMap ) {
226261 SourceMap = require ( 'internal/source_map/source_map' ) . SourceMap ;
227262 }
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- } ;
263+ let sourceMap ;
264+ if ( isGenerated ) {
265+ sourceMap = generatedSourceMapCache . get ( sourceURL ) ;
266+ } else {
267+ sourceMap = esmSourceMapCache . get ( sourceURL ) ;
268+ if ( sourceMap === undefined ) {
269+ for ( const value of cjsSourceMapCache ) {
270+ const filename = ObjectGetValueSafe ( value , 'filename' ) ;
271+ if ( sourceURL === filename ) {
272+ sourceMap = {
273+ data : ObjectGetValueSafe ( value , 'data' )
274+ } ;
275+ }
236276 }
237277 }
238278 }
0 commit comments