@@ -30,12 +30,18 @@ const {
3030 normalizeReferrerURL,
3131} = require ( 'internal/modules/cjs/helpers' ) ;
3232const { validateBoolean } = require ( 'internal/validators' ) ;
33+ const { setMaybeCacheGeneratedSourceMap } = internalBinding ( 'errors' ) ;
34+
3335// Since the CJS module cache is mutable, which leads to memory leaks when
3436// modules are deleted, we use a WeakMap so that the source map cache will
3537// be purged automatically:
3638const cjsSourceMapCache = new IterableWeakMap ( ) ;
3739// The esm cache is not mutable, so we can use a Map without memory concerns:
3840const 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+
3945const { fileURLToPath, pathToFileURL, URL } = require ( 'internal/url' ) ;
4046let SourceMap ;
4147
@@ -71,14 +77,13 @@ function setSourceMapsEnabled(val) {
7177 sourceMapsEnabled = val ;
7278}
7379
74- function maybeCacheSourceMap ( filename , content , cjsModuleInstance ) {
80+ function maybeCacheSourceMap ( filename , content , cjsModuleInstance , isGeneratedSource ) {
7581 const sourceMapsEnabled = getSourceMapsEnabled ( ) ;
7682 if ( ! ( process . env . NODE_V8_COVERAGE || sourceMapsEnabled ) ) return ;
7783 try {
7884 filename = normalizeReferrerURL ( filename ) ;
7985 } 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.
8287 debug ( err ) ;
8388 return ;
8489 }
@@ -96,8 +101,14 @@ function maybeCacheSourceMap(filename, content, cjsModuleInstance) {
96101 data,
97102 url
98103 } ) ;
104+ } else if ( isGeneratedSource ) {
105+ generatedSourceMapCache . set ( filename , {
106+ lineLengths : lineLengths ( content ) ,
107+ data,
108+ url
109+ } ) ;
99110 } 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
101112 // "modules/esm" context.
102113 esmSourceMapCache . set ( filename , {
103114 lineLengths : lineLengths ( content ) ,
@@ -108,6 +119,31 @@ function maybeCacheSourceMap(filename, content, cjsModuleInstance) {
108119 }
109120}
110121
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+
111147function dataFromUrl ( sourceURL , sourceMappingURL ) {
112148 try {
113149 const url = new URL ( sourceMappingURL ) ;
@@ -218,21 +254,26 @@ function appendCJSCache(obj) {
218254 }
219255}
220256
221- function findSourceMap ( sourceURL ) {
222- if ( RegExpPrototypeExec ( / ^ \w + : \/ \/ / , sourceURL ) === null ) {
257+ function findSourceMap ( sourceURL , isGenerated ) {
258+ if ( RegExpPrototypeExec ( kLeadingProtocol , sourceURL ) === null ) {
223259 sourceURL = pathToFileURL ( sourceURL ) . href ;
224260 }
225261 if ( ! SourceMap ) {
226262 SourceMap = require ( 'internal/source_map/source_map' ) . SourceMap ;
227263 }
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+ }
236277 }
237278 }
238279 }
0 commit comments