@@ -6,7 +6,7 @@ import loaderUtils from 'loader-utils';
6
6
import parse from './parse' ;
7
7
8
8
export default function loader ( source , map ) {
9
- const options = loaderUtils . getOptions ( this ) ;
9
+ const options = loaderUtils . getOptions ( this ) || { } ;
10
10
const remainingRequest = loaderUtils . getRemainingRequest ( this ) ;
11
11
const parseResult = parse ( source ) ;
12
12
@@ -19,7 +19,96 @@ export default function loader(source, map) {
19
19
replacer = new ReplaceSource ( new RawSource ( source ) , remainingRequest ) ;
20
20
}
21
21
22
+ const includedStylesheets = new Set ( ) ;
23
+ const includedStylesheetsMediaQuery = new Map ( ) ;
24
+
25
+ parseResult . atImports . forEach ( ( imp ) => {
26
+ if ( loaderUtils . isUrlRequest ( imp . url , options . root ) ) {
27
+ const request = loaderUtils . urlToRequest ( imp . url , options . root ) ;
28
+ replacer . replace ( imp . start , imp . end , '' ) ;
29
+ includedStylesheets . add ( request ) ;
30
+ includedStylesheetsMediaQuery . set ( request , imp . mediaQuery . join ( ' ' ) ) ;
31
+ }
32
+ } ) ;
33
+
34
+ let columns = true ;
35
+ const importedNames = new Map ( ) ;
36
+
37
+ parseResult . imports . forEach ( ( imp ) => {
38
+ importedNames . set ( imp . alias , imp ) ;
39
+ } ) ;
40
+
41
+ const declarations = [ ] ;
42
+ const importReplacements = new Map ( ) ;
43
+
44
+ let id = 0 ;
45
+ for ( const pair of importedNames ) {
46
+ const internalName = `cssLoaderImport${ id } _${ pair [ 1 ] . importName } ` ;
47
+ id += 1 ;
48
+ importReplacements . set ( pair [ 0 ] , internalName ) ;
49
+ declarations . push ( `import { ${ pair [ 1 ] . importName } as ${ internalName } } from ${ JSON . stringify ( pair [ 1 ] . from ) } ;` ) ;
50
+ includedStylesheets . add ( pair [ 1 ] . from ) ;
51
+ }
52
+
53
+ for ( const pair of importReplacements ) {
54
+ const identifier = parseResult . identifiers . get ( pair [ 0 ] ) ;
55
+ if ( identifier ) {
56
+ columns = false ;
57
+ const length = identifier . name . length ;
58
+ identifier . locations . forEach ( ( loc ) => {
59
+ replacer . replace ( loc , loc + length - 1 , `$CSS$LOADER$\{${ pair [ 1 ] } }` ) ;
60
+ } ) ;
61
+ }
62
+ }
63
+
22
64
parseResult . metablocks . forEach ( ( block ) => {
23
65
replacer . replace ( block . start , block . end , '' ) ;
24
66
} ) ;
67
+
68
+ const includedStylesheetsArray = [ ] ;
69
+ for ( const include of includedStylesheets ) {
70
+ const internalName = `cssLoaderImport${ id } ` ;
71
+ id += 1 ;
72
+ declarations . push ( `import ${ internalName } from ${ loaderUtils . stringifyRequest ( this , include ) } ;` ) ;
73
+ includedStylesheetsArray . push ( {
74
+ name : internalName ,
75
+ mediaQuery : includedStylesheetsMediaQuery . get ( include ) || ''
76
+ } ) ;
77
+ }
78
+
79
+ let css ;
80
+ let sourceMap ;
81
+ if ( options . sourceMap ) {
82
+ const sourceAndMap = replacer . sourceAndMap ( typeof options . sourceMap === 'object' ? options . sourceMap : {
83
+ columns : columns
84
+ } ) ;
85
+ css = sourceAndMap . code ;
86
+ sourceMap = sourceAndMap . map ;
87
+ } else {
88
+ css = replacer . source ( ) ;
89
+ sourceMap = null ;
90
+ }
91
+
92
+ const cssJs = JSON . stringify ( css ) . replace ( / \$ C S S \$ L O A D E R \$ \{ ( [ ^ } ] + ) \} / g, ( match , identifer ) => `" + ${ identifer } + "` ) ;
93
+
94
+ return [
95
+ '// css runtime' ,
96
+ `import * as runtime from ${ loaderUtils . stringifyRequest ( this , require . resolve ( "../runtime" ) ) } ;` ,
97
+ '' ,
98
+ '// declarations' ,
99
+ declarations . join ( '\n' ) ,
100
+ '' ,
101
+ '// CSS' ,
102
+ 'export default runtime.a([' ,
103
+ ] . concat (
104
+ includedStylesheetsArray . map ( ( include ) => {
105
+ if ( ! include . mediaQuery ) return ` ${ include . name } ,` ;
106
+ return ` runtime.d(${ include . name } , ${ JSON . stringify ( include . mediaQuery ) } ,` ;
107
+ } )
108
+ ) . concat ( [
109
+ sourceMap ?
110
+ ` runtime.b(module.id, ${ cssJs } , ${ sourceMap } )` :
111
+ ` runtime.c(module.id, ${ cssJs } )` ,
112
+ ']);'
113
+ ] ) . join ( '\n' ) ;
25
114
}
0 commit comments