@@ -47,13 +47,32 @@ const validate = createSchemaValidation(
4747 * @property {ItemCacheFacade } cacheItem cache item
4848 */
4949
50+ const METACHARACTERS_REGEXP = / [ - [ \] \\ / { } ( ) * + ? . ^ $ | ] / g;
51+ const CONTENT_HASH_DETECT_REGEXP = / \[ c o n t e n t h a s h ( : \w + ) ? \] / ;
52+ const CSS_AND_JS_MODULE_EXTENSIONS_REGEXP = / \. ( ( c | m ) ? j s | c s s ) ( $ | \? ) / i;
53+ const CSS_EXTENSION_DETECT_REGEXP = / \. c s s ( $ | \? ) / i;
54+ const MAP_URL_COMMENT_REGEXP = / \[ m a p \] / g;
55+ const URL_COMMENT_REGEXP = / \[ u r l \] / g;
56+ const URL_FORMATTING_REGEXP = / ^ \n \/ \/ ( .* ) $ / ;
57+
58+ /**
59+ * Reset's .lastIndex of stateful Regular Expressions
60+ * For when `test` or `exec` is called on them
61+ * @param {RegExp } regexp Stateful Regular Expression to be reset
62+ * @returns {void }
63+ *
64+ */
65+ const resetRegexpState = regexp => {
66+ regexp . lastIndex = - 1 ;
67+ } ;
68+
5069/**
5170 * Escapes regular expression metacharacters
5271 * @param {string } str String to quote
5372 * @returns {string } Escaped string
5473 */
5574const quoteMeta = str => {
56- return str . replace ( / [ - [ \] \\ / { } ( ) * + ? . ^ $ | ] / g , "\\$&" ) ;
75+ return str . replace ( METACHARACTERS_REGEXP , "\\$&" ) ;
5776} ;
5877
5978/**
@@ -152,7 +171,7 @@ class SourceMapDevToolPlugin {
152171 const fallbackModuleFilenameTemplate = this . fallbackModuleFilenameTemplate ;
153172 const requestShortener = compiler . requestShortener ;
154173 const options = this . options ;
155- options . test = options . test || / \. ( ( c | m ) ? j s | c s s ) ( $ | \? ) / i ;
174+ options . test = options . test || CSS_AND_JS_MODULE_EXTENSIONS_REGEXP ;
156175
157176 const matchObject = ModuleFilenameHelpers . matchObject . bind (
158177 undefined ,
@@ -409,7 +428,9 @@ class SourceMapDevToolPlugin {
409428 sourceMap . file = file ;
410429 const usesContentHash =
411430 sourceMapFilename &&
412- / \[ c o n t e n t h a s h ( : \w + ) ? \] / . test ( sourceMapFilename ) ;
431+ CONTENT_HASH_DETECT_REGEXP . test ( sourceMapFilename ) ;
432+
433+ resetRegexpState ( CONTENT_HASH_DETECT_REGEXP ) ;
413434
414435 // If SourceMap and asset uses contenthash, avoid a circular dependency by hiding hash in `file`
415436 if ( usesContentHash && task . assetInfo . contenthash ) {
@@ -428,13 +449,16 @@ class SourceMapDevToolPlugin {
428449
429450 /** @type {string | false } */
430451 let currentSourceMappingURLComment = sourceMappingURLComment ;
452+ let cssExtensionDetected =
453+ CSS_EXTENSION_DETECT_REGEXP . test ( file ) ;
454+ resetRegexpState ( CSS_EXTENSION_DETECT_REGEXP ) ;
431455 if (
432456 currentSourceMappingURLComment !== false &&
433- / \. c s s ( $ | \? ) / i . test ( file )
457+ cssExtensionDetected
434458 ) {
435459 currentSourceMappingURLComment =
436460 currentSourceMappingURLComment . replace (
437- / ^ \n \/ \/ ( . * ) $ / ,
461+ URL_FORMATTING_REGEXP ,
438462 "\n/*$1*/"
439463 ) ;
440464 }
@@ -516,9 +540,9 @@ class SourceMapDevToolPlugin {
516540 const asset = new ConcatSource (
517541 new RawSource ( source ) ,
518542 currentSourceMappingURLComment
519- . replace ( / \[ m a p \] / g , ( ) => sourceMapString )
543+ . replace ( MAP_URL_COMMENT_REGEXP , ( ) => sourceMapString )
520544 . replace (
521- / \[ u r l \] / g ,
545+ URL_COMMENT_REGEXP ,
522546 ( ) =>
523547 `data:application/json;charset=utf-8;base64,${ Buffer . from (
524548 sourceMapString ,
0 commit comments