@@ -49,6 +49,18 @@ const filenameReservedRegex = /[<>:"/\\|?*]/g;
4949// eslint-disable-next-line no-control-regex
5050const reControlChars = / [ \u0000 - \u001f \u0080 - \u009f ] / g;
5151
52+ function escapeLocalident ( localident ) {
53+ return cssesc (
54+ localident
55+ // For `[hash]` placeholder
56+ . replace ( / ^ ( ( - ? [ 0 - 9 ] ) | - - ) / , '_$1' )
57+ . replace ( filenameReservedRegex , '-' )
58+ . replace ( reControlChars , '-' )
59+ . replace ( / \. / g, '-' ) ,
60+ { isIdentifier : true }
61+ ) ;
62+ }
63+
5264function defaultGetLocalIdent (
5365 loaderContext ,
5466 localIdentName ,
@@ -60,19 +72,9 @@ function defaultGetLocalIdent(
6072 const request = normalizePath ( path . relative ( context , resourcePath ) ) ;
6173
6274 // eslint-disable-next-line no-param-reassign
63- options . content = `${ hashPrefix + request } \x00${ unescape ( localName ) } ` ;
75+ options . content = `${ hashPrefix + request } \x00${ localName } ` ;
6476
65- // Using `[path]` placeholder outputs `/` we need escape their
66- // Also directories can contains invalid characters for css we need escape their too
67- return cssesc (
68- interpolateName ( loaderContext , localIdentName , options )
69- // For `[hash]` placeholder
70- . replace ( / ^ ( ( - ? [ 0 - 9 ] ) | - - ) / , '_$1' )
71- . replace ( filenameReservedRegex , '-' )
72- . replace ( reControlChars , '-' )
73- . replace ( / \. / g, '-' ) ,
74- { isIdentifier : true }
75- ) . replace ( / \\ \[ l o c a l \\ ] / gi, localName ) ;
77+ return interpolateName ( loaderContext , localIdentName , options ) ;
7678}
7779
7880function normalizeUrl ( url , isStringValue ) {
@@ -143,7 +145,8 @@ function getModulesOptions(rawOptions, loaderContext) {
143145 localIdentHashPrefix : '' ,
144146 // eslint-disable-next-line no-undefined
145147 localIdentRegExp : undefined ,
146- getLocalIdent : defaultGetLocalIdent ,
148+ // eslint-disable-next-line no-undefined
149+ getLocalIdent : undefined ,
147150 namedExport : false ,
148151 exportLocalsConvention : 'asIs' ,
149152 exportOnlyLocals : false ,
@@ -281,32 +284,42 @@ function getModulesPlugins(options, loaderContext) {
281284 extractImports ( ) ,
282285 modulesScope ( {
283286 generateScopedName ( exportName ) {
284- let localIdent = getLocalIdent (
285- loaderContext ,
286- localIdentName ,
287- exportName ,
288- {
289- context : localIdentContext ,
290- hashPrefix : localIdentHashPrefix ,
291- regExp : localIdentRegExp ,
292- }
293- ) ;
287+ let localIdent ;
288+
289+ if ( typeof getLocalIdent !== 'undefined' ) {
290+ localIdent = getLocalIdent (
291+ loaderContext ,
292+ localIdentName ,
293+ unescape ( exportName ) ,
294+ {
295+ context : localIdentContext ,
296+ hashPrefix : localIdentHashPrefix ,
297+ regExp : localIdentRegExp ,
298+ }
299+ ) ;
300+ }
294301
295302 // A null/undefined value signals that we should invoke the default
296303 // getLocalIdent method.
297- if ( localIdent == null ) {
304+ if ( typeof localIdent === 'undefined' || localIdent = == null ) {
298305 localIdent = defaultGetLocalIdent (
299306 loaderContext ,
300307 localIdentName ,
301- exportName ,
308+ unescape ( exportName ) ,
302309 {
303310 context : localIdentContext ,
304311 hashPrefix : localIdentHashPrefix ,
305312 regExp : localIdentRegExp ,
306313 }
307314 ) ;
315+
316+ return escapeLocalident ( localIdent ) . replace (
317+ / \\ \[ l o c a l \\ ] / gi,
318+ exportName
319+ ) ;
308320 }
309- return localIdent ;
321+
322+ return escapeLocalident ( localIdent ) ;
310323 } ,
311324 exportGlobals : options . modules . exportGlobals ,
312325 } ) ,
0 commit comments