@@ -17,14 +17,15 @@ import {
1717  getCurrentRequest , 
1818  stringifyRequest , 
1919}  from  'loader-utils' ; 
20+ import  camelCase  from  'lodash/camelCase' ; 
2021
2122import  schema  from  './options.json' ; 
2223import  {  importParser ,  icssParser ,  urlParser  }  from  './plugins' ; 
2324import  { 
2425  getLocalIdent , 
2526  getImportPrefix , 
26-   compileExports , 
2727  placholderRegExps , 
28+   dashesCamelCase , 
2829}  from  './utils' ; 
2930import  Warning  from  './Warning' ; 
3031import  CssSyntaxError  from  './CssSyntaxError' ; 
@@ -137,10 +138,9 @@ export default function loader(content, map, meta) {
137138        . forEach ( ( warning )  =>  this . emitWarning ( new  Warning ( warning ) ) ) ; 
138139
139140      const  messages  =  result . messages  ||  [ ] ; 
140-       const  {  camelCase,  exportOnlyLocals,  importLoaders }  =  options ; 
141141
142142      // Run other loader (`postcss-loader`, `sass-loader` and etc) for importing CSS 
143-       const  importUrlPrefix  =  getImportPrefix ( this ,  importLoaders ) ; 
143+       const  importUrlPrefix  =  getImportPrefix ( this ,  options . importLoaders ) ; 
144144
145145      // Prepare replacer to change from `___CSS_LOADER_IMPORT___INDEX___` to `require('./file.css').locals` 
146146      const  importItemReplacer  =  ( placeholder )  =>  { 
@@ -162,7 +162,7 @@ export default function loader(content, map, meta) {
162162        const  {  item }  =  message ; 
163163        const  importUrl  =  importUrlPrefix  +  urlToRequest ( item . url ) ; 
164164
165-         if  ( exportOnlyLocals )  { 
165+         if  ( options . exportOnlyLocals )  { 
166166          return  `" + require(${ stringifyRequest (  
167167            this ,  
168168            importUrl  
@@ -175,18 +175,65 @@ export default function loader(content, map, meta) {
175175        ) }  ).locals[${ JSON . stringify ( item . export ) } ; 
176176      } ; 
177177
178-       let  exportCode  =  compileExports ( messages ,  camelCase ,  ( valueAsString )  => 
179-         valueAsString . replace ( placholderRegExps . importItemG ,  importItemReplacer ) 
180-       ) ; 
178+       const  exports  =  messages 
179+         . filter ( ( message )  =>  message . type  ===  'export' ) 
180+         . reduce ( ( accumulator ,  message )  =>  { 
181+           const  {  key,  value }  =  message . item ; 
182+ 
183+           let  valueAsString  =  JSON . stringify ( value ) ; 
184+ 
185+           valueAsString  =  valueAsString . replace ( 
186+             placholderRegExps . importItemG , 
187+             importItemReplacer 
188+           ) ; 
189+ 
190+           function  addEntry ( k )  { 
191+             accumulator . push ( `\t${ JSON . stringify ( k ) } ${ valueAsString }  ) ; 
192+           } 
193+ 
194+           let  targetKey ; 
195+ 
196+           switch  ( options . camelCase )  { 
197+             case  true :
198+               addEntry ( key ) ; 
199+               targetKey  =  camelCase ( key ) ; 
200+ 
201+               if  ( targetKey  !==  key )  { 
202+                 addEntry ( targetKey ) ; 
203+               } 
204+               break ; 
205+             case  'dashes' :
206+               addEntry ( key ) ; 
207+               targetKey  =  dashesCamelCase ( key ) ; 
208+ 
209+               if  ( targetKey  !==  key )  { 
210+                 addEntry ( targetKey ) ; 
211+               } 
212+               break ; 
213+             case  'only' :
214+               addEntry ( camelCase ( key ) ) ; 
215+               break ; 
216+             case  'dashesOnly' :
217+               addEntry ( dashesCamelCase ( key ) ) ; 
218+               break ; 
219+             default :
220+               addEntry ( key ) ; 
221+               break ; 
222+           } 
223+ 
224+           return  accumulator ; 
225+         } ,  [ ] ) ; 
181226
182-       if  ( exportOnlyLocals )  { 
227+       if  ( options . exportOnlyLocals )  { 
183228        return  callback ( 
184229          null , 
185-           exportCode  ? `module.exports = ${ exportCode }   : exportCode 
230+           exports . length  >  0 
231+             ? `module.exports = {\n${ exports . join ( ',\n' ) }  
232+             : '' 
186233        ) ; 
187234      } 
188235
189-       const  importCode  =  messages 
236+       const  imports  =  messages 
190237        . filter ( ( message )  =>  message . type  ===  'import' ) 
191238        . map ( ( message )  =>  { 
192239          const  {  url }  =  message . item ; 
@@ -204,56 +251,52 @@ export default function loader(content, map, meta) {
204251            this ,  
205252            importUrl  
206253          ) }  ), ${ JSON . stringify ( media ) } ; 
207-         } ,  this ) 
208-         . join ( '\n' ) ; 
254+         } ,  this ) ; 
209255
210256      let  cssAsString  =  JSON . stringify ( result . css ) . replace ( 
211257        placholderRegExps . importItemG , 
212258        importItemReplacer 
213259      ) ; 
214260
215-       // helper  for ensuring valid CSS strings from requires 
216-       let  urlEscapeHelperCode  =  '' ; 
261+       // Helper  for ensuring valid CSS strings from requires 
262+       let  hasUrlEscapeHelper  =  false ; 
217263
218264      messages 
219265        . filter ( ( message )  =>  message . type  ===  'url' ) 
220266        . forEach ( ( message )  =>  { 
221-           if  ( ! urlEscapeHelperCode )  { 
222-             urlEscapeHelperCode  =  `var escape = require(${ stringifyRequest (  
223-               this ,  
224-               require . resolve ( './runtime/escape.js' )  
225-             ) }  );\n`; 
267+           if  ( ! hasUrlEscapeHelper )  { 
268+             imports . push ( 
269+               `var urlEscape = require(${ stringifyRequest (  
270+                 this ,  
271+                 require . resolve ( './runtime/url-escape.js' )  
272+               ) }  );`
273+             ) ; 
274+ 
275+             hasUrlEscapeHelper  =  true ; 
226276          } 
227277
228278          const  {  item }  =  message ; 
229279          const  {  url,  placeholder }  =  item ; 
280+           // Remove `#hash` and `?#hash` from `require` 
281+           const  [ normalizedUrl ,  singleQuery ,  hashValue ]  =  url . split ( / ( \? ) ? # / ) ; 
282+           const  hash  = 
283+             singleQuery  ||  hashValue 
284+               ? `"${ singleQuery  ? '?'  : '' } ${ hashValue  ? `#${ hashValue }   : '' }  
285+               : '' ; 
286+ 
287+           imports . push ( 
288+             `var ${ placeholder } ${ stringifyRequest (  
289+               this ,  
290+               urlToRequest ( normalizedUrl )  
291+             ) }  )${ hash  ? ` + ${ hash }   : '' } 
292+           ) ; 
230293
231294          cssAsString  =  cssAsString . replace ( 
232295            new  RegExp ( placeholder ,  'g' ) , 
233-             ( )  =>  { 
234-               // Remove `#hash` and `?#hash` from `require` 
235-               const  [ normalizedUrl ,  singleQuery ,  hashValue ]  =  url . split ( 
236-                 / ( \? ) ? # / 
237-               ) ; 
238-               const  hash  = 
239-                 singleQuery  ||  hashValue 
240-                   ? `"${ singleQuery  ? '?'  : '' } ${  
241-                       hashValue  ? `#${ hashValue }   : ''  
242-                     }  "`
243-                   : '' ; 
244- 
245-               return  `" + escape(require(${ stringifyRequest (  
246-                 this ,  
247-                 urlToRequest ( normalizedUrl )  
248-               ) }  )${ hash  ? ` + ${ hash }   : '' } ; 
249-             } 
296+             ( )  =>  `" + ${ placeholder }  
250297          ) ; 
251298        } ) ; 
252299
253-       if  ( exportCode )  { 
254-         exportCode  =  `exports.locals = ${ exportCode }  ; 
255-       } 
256- 
257300      let  newMap  =  result . map ; 
258301
259302      if  ( sourceMap  &&  newMap )  { 
@@ -282,18 +325,21 @@ export default function loader(content, map, meta) {
282325      const  runtimeCode  =  `exports = module.exports = require(${ stringifyRequest (  
283326        this ,  
284327        require . resolve ( './runtime/api' )  
285-       ) }  )(${ ! ! sourceMap } ; 
286-       const  moduleCode  =  `exports.push([module.id, ${ cssAsString } ${  
328+       ) }  )(${ ! ! sourceMap } ; 
329+       const  importCode  = 
330+         imports . length  >  0  ? `// Imports\n${ imports . join ( '\n' ) }   : '' ; 
331+       const  moduleCode  =  `// Module\nexports.push([module.id, ${ cssAsString } ${  
287332        newMap  ? `,${ newMap }   : ''  
288-       }  ]);`; 
333+       }  ]);\n\n`; 
334+       const  exportsCode  = 
335+         exports . length  >  0 
336+           ? `// Exports\nexports.locals = {\n${ exports . join ( ',\n' ) }  
337+           : '' ; 
289338
290339      // Embed runtime 
291340      return  callback ( 
292341        null , 
293-         `${ urlEscapeHelperCode } ${ runtimeCode }   + 
294-           `// imports\n${ importCode }   + 
295-           `// module\n${ moduleCode }   + 
296-           `// exports\n${ exportCode }  
342+         runtimeCode  +  importCode  +  moduleCode  +  exportsCode 
297343      ) ; 
298344    } ) 
299345    . catch ( ( error )  =>  { 
0 commit comments