11import postcss from 'postcss' ;
22import valueParser from 'postcss-value-parser' ;
3- import { extractICSS } from 'icss-utils' ;
3+ import { extractICSS , replaceValueSymbols } from 'icss-utils' ;
44import loaderUtils from 'loader-utils' ;
55
66const pluginName = 'postcss-icss-parser' ;
@@ -9,22 +9,23 @@ export default postcss.plugin(
99 pluginName ,
1010 ( ) =>
1111 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 ) ;
1514
16- Object . keys ( icss . icssImports ) . forEach ( ( key ) => {
15+ let index = 0 ;
16+
17+ Object . keys ( icssImports ) . forEach ( ( key ) => {
1718 const url = loaderUtils . parseString ( key ) ;
1819
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 ;
2122
22- imports [ `$ ${ prop } ` ] = index ;
23+ importReplacements [ prop ] = `___CSS_LOADER_IMPORT___ ${ index } ___` ;
2324
2425 result . messages . push ( {
2526 pluginName,
2627 type : 'icss-import' ,
27- item : { url, export : icss . icssImports [ key ] [ prop ] , index } ,
28+ item : { url, export : icssImports [ key ] [ prop ] , index } ,
2829 } ) ;
2930
3031 const alreadyIncluded = result . messages . find (
@@ -56,41 +57,43 @@ export default postcss.plugin(
5657 }
5758
5859 const token = node . value ;
59- const importIndex = imports [ `$ ${ token } ` ] ;
60+ const replacement = importReplacements [ token ] ;
6061
61- if ( typeof importIndex === 'number' ) {
62+ if ( replacement ) {
6263 // eslint-disable-next-line no-param-reassign
63- node . value = `___CSS_LOADER_IMPORT___ ${ importIndex } ___` ;
64+ node . value = replacement ;
6465 }
6566 } ) ;
6667
6768 return tokens . toString ( ) ;
6869 }
6970
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 ) {
8184 // eslint-disable-next-line no-param-reassign
82- atrule . params = replaceImportsInString ( atrule . params . toString ( ) ) ;
85+ node . params = replaceImportsInString ( node . params . toString ( ) ) ;
8386 }
8487 } ) ;
8588
8689 // Replace tokens in export
87- Object . keys ( exports ) . forEach ( ( exportName ) => {
90+ Object . keys ( icssExports ) . forEach ( ( exportName ) => {
8891 result . messages . push ( {
8992 pluginName,
9093 type : 'export' ,
9194 item : {
9295 key : exportName ,
93- value : replaceImportsInString ( exports [ exportName ] ) ,
96+ value : replaceImportsInString ( icssExports [ exportName ] ) ,
9497 } ,
9598 } ) ;
9699 } ) ;
0 commit comments