11import postcss from 'postcss' ;
22import { extractICSS , replaceValueSymbols , replaceSymbols } from 'icss-utils' ;
3- import { urlToRequest } from 'loader-utils' ;
43
5- function makeRequestableIcssImports ( icssImports ) {
4+ import { normalizeUrl , resolveRequests , isUrlRequestable } from '../utils' ;
5+
6+ function makeRequestableIcssImports ( icssImports , rootContext ) {
67 return Object . keys ( icssImports ) . reduce ( ( accumulator , url ) => {
78 const tokensMap = icssImports [ url ] ;
89 const tokens = Object . keys ( tokensMap ) ;
@@ -11,16 +12,27 @@ function makeRequestableIcssImports(icssImports) {
1112 return accumulator ;
1213 }
1314
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+ }
1522
16- if ( ! accumulator [ normalizedUrl ] ) {
23+ const key = typeof normalizedUrl !== 'undefined' ? normalizedUrl : url ;
24+
25+ if ( ! accumulator [ key ] ) {
1726 // eslint-disable-next-line no-param-reassign
18- accumulator [ normalizedUrl ] = tokensMap ;
27+ accumulator [ key ] = { url , tokenMap : tokensMap } ;
1928 } else {
2029 // 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+ } ,
2436 } ;
2537 }
2638
@@ -31,55 +43,104 @@ function makeRequestableIcssImports(icssImports) {
3143export default postcss . plugin (
3244 'postcss-icss-parser' ,
3345 ( 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
5552 ) ;
5653
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+ }
63121
64- importReplacements [ token ] = replacementName ;
122+ try {
123+ await Promise . all ( tasks ) ;
124+ } catch ( error ) {
125+ reject ( error ) ;
126+ }
65127
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 ) ;
70130 }
71- }
72131
73- if ( Object . keys ( importReplacements ) . length > 0 ) {
74- replaceSymbols ( css , importReplacements ) ;
75- }
132+ const { icssExports } = extractedICSS ;
76133
77- const { icssExports } = extractedICSS ;
134+ for ( const name of Object . keys ( icssExports ) ) {
135+ const value = replaceValueSymbols (
136+ icssExports [ name ] ,
137+ importReplacements
138+ ) ;
78139
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+ }
81142
82- result . messages . push ( { type : 'export' , value : { name , value } } ) ;
83- }
143+ resolve ( ) ;
144+ } ) ;
84145 }
85146) ;
0 commit comments