1
1
import postcss from 'postcss' ;
2
2
import valueParser from 'postcss-value-parser' ;
3
- import { extractICSS } from 'icss-utils' ;
3
+ import { extractICSS , replaceValueSymbols } from 'icss-utils' ;
4
4
import loaderUtils from 'loader-utils' ;
5
5
6
6
const pluginName = 'postcss-icss-parser' ;
@@ -9,22 +9,23 @@ export default postcss.plugin(
9
9
pluginName ,
10
10
( ) =>
11
11
function process ( css , result ) {
12
- const imports = { } ;
13
- const icss = extractICSS ( css ) ;
14
- const exports = icss . icssExports ;
12
+ const importReplacements = Object . create ( null ) ;
13
+ const { icssImports, icssExports } = extractICSS ( css ) ;
15
14
16
- Object . keys ( icss . icssImports ) . forEach ( ( key ) => {
15
+ let index = 0 ;
16
+
17
+ Object . keys ( icssImports ) . forEach ( ( key ) => {
17
18
const url = loaderUtils . parseString ( key ) ;
18
19
19
- Object . keys ( icss . icssImports [ key ] ) . forEach ( ( prop ) => {
20
- const index = Object . keys ( imports ) . length ;
20
+ Object . keys ( icssImports [ key ] ) . forEach ( ( prop ) => {
21
+ index += 1 ;
21
22
22
- imports [ `$ ${ prop } ` ] = index ;
23
+ importReplacements [ prop ] = `___CSS_LOADER_IMPORT___ ${ index } ___` ;
23
24
24
25
result . messages . push ( {
25
26
pluginName,
26
27
type : 'icss-import' ,
27
- item : { url, export : icss . icssImports [ key ] [ prop ] , index } ,
28
+ item : { url, export : icssImports [ key ] [ prop ] , index } ,
28
29
} ) ;
29
30
30
31
const alreadyIncluded = result . messages . find (
@@ -56,41 +57,43 @@ export default postcss.plugin(
56
57
}
57
58
58
59
const token = node . value ;
59
- const importIndex = imports [ `$ ${ token } ` ] ;
60
+ const replacement = importReplacements [ token ] ;
60
61
61
- if ( typeof importIndex === 'number' ) {
62
+ if ( replacement ) {
62
63
// eslint-disable-next-line no-param-reassign
63
- node . value = `___CSS_LOADER_IMPORT___ ${ importIndex } ___` ;
64
+ node . value = replacement ;
64
65
}
65
66
} ) ;
66
67
67
68
return tokens . toString ( ) ;
68
69
}
69
70
70
- // Replace tokens in declarations
71
- css . walkDecls ( ( decl ) => {
72
- // eslint-disable-next-line no-param-reassign
73
- decl . value = replaceImportsInString ( decl . value . toString ( ) ) ;
74
- } ) ;
75
-
76
- // Replace tokens in at-rules
77
- css . walkAtRules ( ( atrule ) => {
78
- // Due reusing `ast` from `postcss-loader` some plugins may lack
79
- // `params` property, we need to account for this possibility
80
- if ( atrule . params ) {
71
+ // Replace tokens
72
+ css . walk ( ( node ) => {
73
+ // Due reusing `ast` from `postcss-loader` some plugins may remove `value`, `selector` or `params` properties
74
+ if ( node . type === 'decl' && node . value ) {
75
+ // eslint-disable-next-line no-param-reassign
76
+ node . value = replaceImportsInString ( node . value . toString ( ) ) ;
77
+ } else if ( node . type === 'rule' && node . selector ) {
78
+ // eslint-disable-next-line no-param-reassign
79
+ node . selector = replaceValueSymbols (
80
+ node . selector . toString ( ) ,
81
+ importReplacements
82
+ ) ;
83
+ } else if ( node . type === 'atrule' && node . params ) {
81
84
// eslint-disable-next-line no-param-reassign
82
- atrule . params = replaceImportsInString ( atrule . params . toString ( ) ) ;
85
+ node . params = replaceImportsInString ( node . params . toString ( ) ) ;
83
86
}
84
87
} ) ;
85
88
86
89
// Replace tokens in export
87
- Object . keys ( exports ) . forEach ( ( exportName ) => {
90
+ Object . keys ( icssExports ) . forEach ( ( exportName ) => {
88
91
result . messages . push ( {
89
92
pluginName,
90
93
type : 'export' ,
91
94
item : {
92
95
key : exportName ,
93
- value : replaceImportsInString ( exports [ exportName ] ) ,
96
+ value : replaceImportsInString ( icssExports [ exportName ] ) ,
94
97
} ,
95
98
} ) ;
96
99
} ) ;
0 commit comments