1
- const postcss = require ( 'postcss' )
2
- const { default : replaceSymbols , replaceAll } = require ( 'icss-replace-symbols' )
1
+ import postcss from 'postcss'
2
+ import {
3
+ replaceSymbols ,
4
+ replaceValueSymbols ,
5
+ extractICSS ,
6
+ createICSSRules
7
+ } from 'icss-utils'
3
8
4
9
const matchImports = / ^ ( .+ ?| \( [ \s \S ] + ?\) ) \s + f r o m \s + ( " [ ^ " ] * " | ' [ ^ ' ] * ' | [ \w - ] + ) $ /
5
10
const matchValueDefinition = / (?: \s + | ^ ) ( [ \w - ] + ) : ? \s + ( .+ ?) \s * $ / g
6
11
const matchImport = / ^ ( [ \w - ] + ) (?: \s + a s \s + ( [ \w - ] + ) ) ? /
7
12
8
- const addImportsRules = ( css , imports ) => {
9
- const rules = imports . map ( ( { path, aliases } ) => {
10
- const declarations = Object . keys ( aliases ) . map ( key =>
11
- postcss . decl ( {
12
- prop : key ,
13
- value : aliases [ key ] ,
14
- raws : { before : '\n ' }
15
- } )
16
- )
17
- return postcss
18
- . rule ( {
19
- selector : `:import(${ path } )` ,
20
- raws : { after : '\n' }
21
- } )
22
- . append ( declarations )
23
- } )
24
- css . prepend ( rules )
25
- }
26
-
27
- const addExportsRule = ( css , exports ) => {
28
- const declarations = Object . keys ( exports ) . map ( key =>
29
- postcss . decl ( {
30
- prop : key ,
31
- value : exports [ key ] ,
32
- raws : { before : '\n ' }
33
- } )
34
- )
35
- const rule = postcss
36
- . rule ( {
37
- selector : `:export` ,
38
- raws : { after : '\n' }
39
- } )
40
- . append ( declarations )
41
- css . prepend ( rule )
42
- }
43
-
44
- let importIndex = 0
45
- const createImportedName = importName =>
46
- `i__const_${ importName . replace ( / \W / g, '_' ) } _${ importIndex ++ } `
13
+ // 'i' prefix to prevent postcss parsing "_" as css hook
14
+ const getAliasName = ( name , index ) =>
15
+ `i__value_${ name . replace ( / \W / g, '_' ) } _${ index } `
47
16
48
17
module . exports = postcss . plugin ( 'postcss-modules-values' , ( ) => (
49
18
css ,
50
19
result
51
20
) => {
52
- let importAliases = [ ]
53
- let definitions = { }
21
+ const { icssImports, icssExports } = extractICSS ( css )
22
+ let importIndex = 0
23
+ const createImportedName = ( path , name ) => {
24
+ const importedName = getAliasName ( name , importIndex )
25
+ if ( icssImports [ path ] && icssImports [ path ] [ importedName ] ) {
26
+ importIndex += 1
27
+ return createImportedName ( path , name )
28
+ }
29
+ importIndex += 1
30
+ return importedName
31
+ }
54
32
55
33
const addDefinition = atRule => {
56
34
let matches
57
35
while ( ( matches = matchValueDefinition . exec ( atRule . params ) ) ) {
58
36
let [ , key , value ] = matches
59
37
// Add to the definitions, knowing that values can refer to each other
60
- definitions [ key ] = replaceAll ( definitions , value )
38
+ icssExports [ key ] = replaceValueSymbols ( value , icssExports )
61
39
atRule . remove ( )
62
40
}
63
41
}
@@ -67,16 +45,16 @@ module.exports = postcss.plugin('postcss-modules-values', () => (
67
45
if ( matches ) {
68
46
let [ , aliasesString , path ] = matches
69
47
// We can use constants for path names
70
- if ( definitions [ path ] ) path = definitions [ path ]
48
+ if ( icssExports [ path ] ) path = icssExports [ path ]
71
49
let aliases = aliasesString
72
50
. replace ( / ^ \( \s * ( [ \s \S ] + ) \s * \) $ / , '$1' )
73
51
. split ( / \s * , \s * / )
74
52
. map ( alias => {
75
53
let tokens = matchImport . exec ( alias )
76
54
if ( tokens ) {
77
- let [ , /*match*/ theirName , myName = theirName ] = tokens
78
- let importedName = createImportedName ( myName )
79
- definitions [ myName ] = importedName
55
+ let [ , theirName , myName = theirName ] = tokens
56
+ let importedName = createImportedName ( path , myName )
57
+ icssExports [ myName ] = importedName
80
58
return { theirName, importedName }
81
59
} else {
82
60
throw new Error ( `@import statement "${ alias } " is invalid!` )
@@ -86,7 +64,7 @@ module.exports = postcss.plugin('postcss-modules-values', () => (
86
64
acc [ importedName ] = theirName
87
65
return acc
88
66
} , { } )
89
- importAliases . push ( { path, aliases } )
67
+ icssImports [ path ] = Object . assign ( { } , icssImports [ path ] , aliases )
90
68
atRule . remove ( )
91
69
}
92
70
}
@@ -104,13 +82,9 @@ module.exports = postcss.plugin('postcss-modules-values', () => (
104
82
}
105
83
} )
106
84
107
- /* If we have no definitions, don't continue */
108
- if ( Object . keys ( definitions ) . length === 0 ) return
109
-
110
- /* Perform replacements */
111
- replaceSymbols ( css , definitions )
85
+ if ( Object . keys ( icssExports ) . length === 0 ) return
112
86
113
- addExportsRule ( css , definitions )
87
+ replaceSymbols ( css , icssExports )
114
88
115
- addImportsRules ( css , importAliases )
89
+ css . prepend ( createICSSRules ( icssImports , icssExports ) )
116
90
} )
0 commit comments