1- const matchImports = / ^ ( .+ ?) \s + f r o m \s + (?: " ( [ ^ " ] + ) " | ' ( [ ^ ' ] + ) ' ) $ /
1+ import postcss from 'postcss' ;
2+
3+ const matchImports = / ^ ( .+ ?) \s + f r o m \s + ( " [ ^ " ] * " | ' [ ^ ' ] * ' ) $ /
24const matchLet = / (?: , \s + | ^ ) ( [ \w - ] + ) : ? \s + ( " [ ^ " ] * " | ' [ ^ ' ] * ' | [ ^ , ] + ) \s ? / g
35const matchConstName = / [ \w - ] + / g
6+ const matchImport = / ^ ( [ \w - ] + ) (?: \s + a s \s + ( [ \w - ] + ) ) ? /
7+ let options = { }
8+ let importIndex = 0
9+ let createImportedName = options && options . createImportedName || ( ( importName /*, path*/ ) => `i__const_${ importName . replace ( / \W / g, '_' ) } _${ importIndex ++ } ` )
10+
11+ const replace = ( declarations , object , propName ) => {
12+ let matches
13+ while ( matches = matchConstName . exec ( object [ propName ] ) ) {
14+ let replacement = declarations [ matches [ 0 ] ]
15+ if ( replacement ) {
16+ object [ propName ] = object [ propName ] . slice ( 0 , matches . index ) + replacement + object [ propName ] . slice ( matchConstName . lastIndex )
17+ matchConstName . lastIndex -= matches [ 0 ] . length - replacement . length
18+ }
19+ }
20+ }
421
522export default css => {
23+ /* Find any local let rules and store them*/
624 let declarations = { }
725 css . eachAtRule ( / ^ - ? l e t $ / , atRule => {
826 let matches
@@ -11,23 +29,61 @@ export default css => {
1129 declarations [ key ] = value
1230 }
1331 } )
32+
33+ console . log ( declarations )
34+ /* We want to export anything defined by now, but don't add it to the CSS yet or
35+ it well get picked up by the replacement stuff */
36+ let exportDeclarations = Object . keys ( declarations ) . map ( key => postcss . decl ( {
37+ value : declarations [ key ] ,
38+ prop : key ,
39+ before : "\n " ,
40+ _autoprefixerDisabled : true
41+ } ) )
42+
43+ /* Find imports and insert ICSS tmp vars */
44+ let importAliases = [ ]
1445 css . eachAtRule ( / ^ - ? i m p o r t $ / , atRule => {
15- let imports = matchImports . exec ( atRule . params )
16- if ( imports ) {
17- //console.log(imports)
18- } else {
19- console . log ( atRule . params )
46+ let matches = matchImports . exec ( atRule . params )
47+ if ( matches ) {
48+ let [ /*match*/ , aliases , path ] = matches
49+ let imports = aliases . split ( / \s * , \s * / ) . map ( alias => {
50+ let tokens = matchImport . exec ( alias )
51+ if ( tokens ) {
52+ let [ /*match*/ , theirName , myName = theirName ] = tokens
53+ let importedName = createImportedName ( myName )
54+ declarations [ myName ] = importedName
55+ return { theirName, importedName}
56+ } else {
57+ throw new Error ( `@import statement "${ alias } " is invalid!` )
58+ }
59+ } )
60+ importAliases . push ( { path, imports} )
2061 }
2162 } )
63+
2264 /* Perform replacements */
23- css . eachDecl ( decl => {
24- let matches
25- while ( matches = matchConstName . exec ( decl . value ) ) {
26- let replacement = declarations [ matches [ 0 ] ]
27- if ( replacement ) {
28- decl . value = decl . value . slice ( 0 , matches . index ) + replacement + decl . value . slice ( matchConstName . lastIndex )
29- matchConstName . lastIndex -= matches [ 0 ] . length - replacement . length
30- }
31- }
65+ css . eachDecl ( decl => replace ( declarations , decl , 'value' ) )
66+
67+ /* Add import rules */
68+ importAliases . forEach ( ( { path, imports} ) => {
69+ css . prepend ( postcss . rule ( {
70+ selector : `:import(${ path } )` ,
71+ after : "\n" ,
72+ nodes : imports . map ( ( { theirName, importedName} ) => postcss . decl ( {
73+ value : theirName ,
74+ prop : importedName ,
75+ before : "\n " ,
76+ _autoprefixerDisabled : true
77+ } ) )
78+ } ) )
3279 } )
80+
81+ /* Add export rules if any */
82+ if ( exportDeclarations . length > 0 ) {
83+ css . prepend ( postcss . rule ( {
84+ selector : `:export` ,
85+ after : "\n" ,
86+ nodes : exportDeclarations
87+ } ) )
88+ }
3389}
0 commit comments