1
- const matchImports = / ^ ( .+ ?) \s + f r o m \s + (?: " ( [ ^ " ] + ) " | ' ( [ ^ ' ] + ) ' ) $ /
1
+ import postcss from 'postcss' ;
2
+
3
+ const matchImports = / ^ ( .+ ?) \s + f r o m \s + ( " [ ^ " ] * " | ' [ ^ ' ] * ' ) $ /
2
4
const matchLet = / (?: , \s + | ^ ) ( [ \w - ] + ) : ? \s + ( " [ ^ " ] * " | ' [ ^ ' ] * ' | [ ^ , ] + ) \s ? / g
3
5
const 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
+ }
4
21
5
22
export default css => {
23
+ /* Find any local let rules and store them*/
6
24
let declarations = { }
7
25
css . eachAtRule ( / ^ - ? l e t $ / , atRule => {
8
26
let matches
@@ -11,23 +29,61 @@ export default css => {
11
29
declarations [ key ] = value
12
30
}
13
31
} )
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 = [ ]
14
45
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} )
20
61
}
21
62
} )
63
+
22
64
/* 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
+ } ) )
32
79
} )
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
+ }
33
89
}
0 commit comments