1
1
import postcss from 'postcss' ;
2
2
import { extractICSS , replaceValueSymbols , replaceSymbols } from 'icss-utils' ;
3
- import { urlToRequest } from 'loader-utils' ;
4
3
5
- function makeRequestableIcssImports ( icssImports ) {
4
+ import { normalizeUrl , resolveRequests , isUrlRequestable } from '../utils' ;
5
+
6
+ function makeRequestableIcssImports ( icssImports , rootContext ) {
6
7
return Object . keys ( icssImports ) . reduce ( ( accumulator , url ) => {
7
8
const tokensMap = icssImports [ url ] ;
8
9
const tokens = Object . keys ( tokensMap ) ;
@@ -11,16 +12,27 @@ function makeRequestableIcssImports(icssImports) {
11
12
return accumulator ;
12
13
}
13
14
14
- const normalizedUrl = urlToRequest ( url ) ;
15
+ const isRequestable = isUrlRequestable ( url ) ;
16
+
17
+ let normalizedUrl ;
18
+
19
+ if ( isRequestable ) {
20
+ normalizedUrl = normalizeUrl ( url , true , rootContext ) ;
21
+ }
15
22
16
- if ( ! accumulator [ normalizedUrl ] ) {
23
+ const key = typeof normalizedUrl !== 'undefined' ? normalizedUrl : url ;
24
+
25
+ if ( ! accumulator [ key ] ) {
17
26
// eslint-disable-next-line no-param-reassign
18
- accumulator [ normalizedUrl ] = tokensMap ;
27
+ accumulator [ key ] = { url , tokenMap : tokensMap } ;
19
28
} else {
20
29
// eslint-disable-next-line no-param-reassign
21
- accumulator [ normalizedUrl ] = {
22
- ...accumulator [ normalizedUrl ] ,
23
- ...tokensMap ,
30
+ accumulator [ key ] = {
31
+ url,
32
+ tokenMap : {
33
+ ...accumulator [ key ] . tokenMap ,
34
+ ...tokensMap ,
35
+ } ,
24
36
} ;
25
37
}
26
38
@@ -31,55 +43,104 @@ function makeRequestableIcssImports(icssImports) {
31
43
export default postcss . plugin (
32
44
'postcss-icss-parser' ,
33
45
( options ) => ( css , result ) => {
34
- const importReplacements = Object . create ( null ) ;
35
- const extractedICSS = extractICSS ( css ) ;
36
- const icssImports = makeRequestableIcssImports ( extractedICSS . icssImports ) ;
37
-
38
- for ( const [ importIndex , url ] of Object . keys ( icssImports ) . entries ( ) ) {
39
- const importName = `___CSS_LOADER_ICSS_IMPORT_${ importIndex } ___` ;
40
-
41
- result . messages . push (
42
- {
43
- type : 'import' ,
44
- value : {
45
- // 'CSS_LOADER_ICSS_IMPORT'
46
- order : 0 ,
47
- importName,
48
- url : options . urlHandler ? options . urlHandler ( url ) : url ,
49
- } ,
50
- } ,
51
- {
52
- type : 'api-import' ,
53
- value : { type : 'internal' , importName, dedupe : true } ,
54
- }
46
+ return new Promise ( async ( resolve , reject ) => {
47
+ const importReplacements = Object . create ( null ) ;
48
+ const extractedICSS = extractICSS ( css ) ;
49
+ const icssImports = makeRequestableIcssImports (
50
+ extractedICSS . icssImports ,
51
+ options . rootContext
55
52
) ;
56
53
57
- const tokenMap = icssImports [ url ] ;
58
- const tokens = Object . keys ( tokenMap ) ;
59
-
60
- for ( const [ replacementIndex , token ] of tokens . entries ( ) ) {
61
- const replacementName = `___CSS_LOADER_ICSS_IMPORT_${ importIndex } _REPLACEMENT_${ replacementIndex } ___` ;
62
- const localName = tokenMap [ token ] ;
54
+ const tasks = [ ] ;
55
+
56
+ let index = 0 ;
57
+
58
+ for ( const [ importIndex , normalizedUrl ] of Object . keys (
59
+ icssImports
60
+ ) . entries ( ) ) {
61
+ const { url } = icssImports [ normalizedUrl ] ;
62
+
63
+ index += 1 ;
64
+
65
+ tasks . push (
66
+ Promise . resolve ( index ) . then ( async ( currentIndex ) => {
67
+ const importName = `___CSS_LOADER_ICSS_IMPORT_${ importIndex } ___` ;
68
+ const { resolver, context } = options ;
69
+
70
+ let resolvedUrl ;
71
+
72
+ try {
73
+ resolvedUrl = await resolveRequests ( resolver , context , [
74
+ ...new Set ( [ normalizedUrl , url ] ) ,
75
+ ] ) ;
76
+ } catch ( error ) {
77
+ throw error ;
78
+ }
79
+
80
+ result . messages . push (
81
+ {
82
+ type : 'import' ,
83
+ value : {
84
+ // 'CSS_LOADER_ICSS_IMPORT'
85
+ order : 0 ,
86
+ importName,
87
+ url : options . urlHandler ( resolvedUrl ) ,
88
+ index : currentIndex ,
89
+ } ,
90
+ } ,
91
+ {
92
+ type : 'api-import' ,
93
+ value : {
94
+ // 'CSS_LOADER_ICSS_IMPORT'
95
+ order : 0 ,
96
+ type : 'internal' ,
97
+ importName,
98
+ dedupe : true ,
99
+ index : currentIndex ,
100
+ } ,
101
+ }
102
+ ) ;
103
+
104
+ const { tokenMap } = icssImports [ normalizedUrl ] ;
105
+ const tokens = Object . keys ( tokenMap ) ;
106
+
107
+ for ( const [ replacementIndex , token ] of tokens . entries ( ) ) {
108
+ const replacementName = `___CSS_LOADER_ICSS_IMPORT_${ importIndex } _REPLACEMENT_${ replacementIndex } ___` ;
109
+ const localName = tokenMap [ token ] ;
110
+
111
+ importReplacements [ token ] = replacementName ;
112
+
113
+ result . messages . push ( {
114
+ type : 'icss-replacement' ,
115
+ value : { replacementName, importName, localName } ,
116
+ } ) ;
117
+ }
118
+ } )
119
+ ) ;
120
+ }
63
121
64
- importReplacements [ token ] = replacementName ;
122
+ try {
123
+ await Promise . all ( tasks ) ;
124
+ } catch ( error ) {
125
+ reject ( error ) ;
126
+ }
65
127
66
- result . messages . push ( {
67
- type : 'icss-replacement' ,
68
- value : { replacementName, importName, localName } ,
69
- } ) ;
128
+ if ( Object . keys ( importReplacements ) . length > 0 ) {
129
+ replaceSymbols ( css , importReplacements ) ;
70
130
}
71
- }
72
131
73
- if ( Object . keys ( importReplacements ) . length > 0 ) {
74
- replaceSymbols ( css , importReplacements ) ;
75
- }
132
+ const { icssExports } = extractedICSS ;
76
133
77
- const { icssExports } = extractedICSS ;
134
+ for ( const name of Object . keys ( icssExports ) ) {
135
+ const value = replaceValueSymbols (
136
+ icssExports [ name ] ,
137
+ importReplacements
138
+ ) ;
78
139
79
- for ( const name of Object . keys ( icssExports ) ) {
80
- const value = replaceValueSymbols ( icssExports [ name ] , importReplacements ) ;
140
+ result . messages . push ( { type : 'export' , value : { name , value } } ) ;
141
+ }
81
142
82
- result . messages . push ( { type : 'export' , value : { name , value } } ) ;
83
- }
143
+ resolve ( ) ;
144
+ } ) ;
84
145
}
85
146
) ;
0 commit comments