1
- import postcss from 'postcss' ;
2
- import topologicalSort from './topologicalSort' ;
1
+ const postcss = require ( 'postcss' )
2
+ const topologicalSort = require ( './topologicalSort' )
3
3
4
- const declWhitelist = [ 'composes' ] ;
5
- const declFilter = new RegExp ( `^(${ declWhitelist . join ( '|' ) } )$` ) ;
6
- const matchImports = / ^ ( .+ ?) \s + f r o m \s + (?: " ( [ ^ " ] + ) " | ' ( [ ^ ' ] + ) ' | ( g l o b a l ) ) $ / ;
7
- const icssImport = / ^ : i m p o r t \( (?: " ( [ ^ " ] + ) " | ' ( [ ^ ' ] + ) ' ) \) / ;
4
+ const declWhitelist = [ 'composes' ]
5
+ const declFilter = new RegExp ( `^(${ declWhitelist . join ( '|' ) } )$` )
6
+ const matchImports = / ^ ( .+ ?) \s + f r o m \s + (?: " ( [ ^ " ] + ) " | ' ( [ ^ ' ] + ) ' | ( g l o b a l ) ) $ /
7
+ const icssImport = / ^ : i m p o r t \( (?: " ( [ ^ " ] + ) " | ' ( [ ^ ' ] + ) ' ) \) /
8
8
9
- const VISITED_MARKER = 1 ;
9
+ const VISITED_MARKER = 1
10
10
11
11
function createParentName ( rule , root ) {
12
- return `__${ root . index ( rule . parent ) } _${ rule . selector } ` ;
12
+ return `__${ root . index ( rule . parent ) } _${ rule . selector } `
13
13
}
14
14
15
15
function serializeImports ( imports ) {
16
- return imports . map ( importPath => '`' + importPath + '`' ) . join ( ', ' ) ;
16
+ return imports . map ( importPath => '`' + importPath + '`' ) . join ( ', ' )
17
17
}
18
18
19
19
/**
@@ -38,132 +38,143 @@ function serializeImports(imports) {
38
38
* }
39
39
*/
40
40
function addImportToGraph ( importId , parentId , graph , visited ) {
41
- const siblingsId = parentId + '_' + 'siblings' ;
42
- const visitedId = parentId + '_' + importId ;
41
+ const siblingsId = parentId + '_' + 'siblings'
42
+ const visitedId = parentId + '_' + importId
43
43
44
44
if ( visited [ visitedId ] !== VISITED_MARKER ) {
45
- if ( ! Array . isArray ( visited [ siblingsId ] ) ) visited [ siblingsId ] = [ ] ;
45
+ if ( ! Array . isArray ( visited [ siblingsId ] ) ) visited [ siblingsId ] = [ ]
46
46
47
- const siblings = visited [ siblingsId ] ;
47
+ const siblings = visited [ siblingsId ]
48
48
49
49
if ( Array . isArray ( graph [ importId ] ) )
50
- graph [ importId ] = graph [ importId ] . concat ( siblings ) ;
51
- else
52
- graph [ importId ] = siblings . slice ( ) ;
50
+ graph [ importId ] = graph [ importId ] . concat ( siblings )
51
+ else graph [ importId ] = siblings . slice ( )
53
52
54
- visited [ visitedId ] = VISITED_MARKER ;
55
- siblings . push ( importId ) ;
53
+ visited [ visitedId ] = VISITED_MARKER
54
+ siblings . push ( importId )
56
55
}
57
56
}
58
57
59
- const processor = postcss . plugin ( 'modules-extract-imports' , function ( options = { } ) {
60
- const failOnWrongOrder = options . failOnWrongOrder ;
58
+ module . exports = postcss . plugin ( 'modules-extract-imports' , function (
59
+ options = { }
60
+ ) {
61
+ const failOnWrongOrder = options . failOnWrongOrder
61
62
62
63
return css => {
63
- const graph = { } ;
64
- const visited = { } ;
64
+ const graph = { }
65
+ const visited = { }
65
66
66
- const existingImports = { } ;
67
- const importDecls = { } ;
68
- const imports = { } ;
67
+ const existingImports = { }
68
+ const importDecls = { }
69
+ const imports = { }
69
70
70
- let importIndex = 0 ;
71
+ let importIndex = 0
71
72
72
73
const createImportedName = typeof options . createImportedName !== 'function'
73
- ? ( importName /*, path*/ ) => `i__imported_${ importName . replace ( / \W / g, '_' ) } _${ importIndex ++ } `
74
- : options . createImportedName ;
74
+ ? ( importName /*, path*/ ) =>
75
+ `i__imported_${ importName . replace ( / \W / g, '_' ) } _${ importIndex ++ } `
76
+ : options . createImportedName
75
77
76
78
// Check the existing imports order and save refs
77
79
css . walkRules ( rule => {
78
- const matches = icssImport . exec ( rule . selector ) ;
80
+ const matches = icssImport . exec ( rule . selector )
79
81
80
82
if ( matches ) {
81
- const [ /*match*/ , doubleQuotePath , singleQuotePath ] = matches ;
82
- const importPath = doubleQuotePath || singleQuotePath ;
83
+ const [ , /*match*/ doubleQuotePath , singleQuotePath ] = matches
84
+ const importPath = doubleQuotePath || singleQuotePath
83
85
84
- addImportToGraph ( importPath , 'root' , graph , visited ) ;
86
+ addImportToGraph ( importPath , 'root' , graph , visited )
85
87
86
- existingImports [ importPath ] = rule ;
88
+ existingImports [ importPath ] = rule
87
89
}
88
- } ) ;
90
+ } )
89
91
90
92
// Find any declaration that supports imports
91
93
css . walkDecls ( declFilter , decl => {
92
- let matches = decl . value . match ( matchImports ) ;
93
- let tmpSymbols ;
94
+ let matches = decl . value . match ( matchImports )
95
+ let tmpSymbols
94
96
95
97
if ( matches ) {
96
- let [ /*match*/ , symbols , doubleQuotePath , singleQuotePath , global ] = matches ;
98
+ let [
99
+ ,
100
+ /*match*/ symbols ,
101
+ doubleQuotePath ,
102
+ singleQuotePath ,
103
+ global
104
+ ] = matches
97
105
98
106
if ( global ) {
99
107
// Composing globals simply means changing these classes to wrap them in global(name)
100
- tmpSymbols = symbols . split ( / \s + / ) . map ( s => `global(${ s } )` ) ;
108
+ tmpSymbols = symbols . split ( / \s + / ) . map ( s => `global(${ s } )` )
101
109
} else {
102
- const importPath = doubleQuotePath || singleQuotePath ;
103
- const parentRule = createParentName ( decl . parent , css ) ;
110
+ const importPath = doubleQuotePath || singleQuotePath
111
+ const parentRule = createParentName ( decl . parent , css )
104
112
105
- addImportToGraph ( importPath , parentRule , graph , visited ) ;
113
+ addImportToGraph ( importPath , parentRule , graph , visited )
106
114
107
- importDecls [ importPath ] = decl ;
108
- imports [ importPath ] = imports [ importPath ] || { } ;
115
+ importDecls [ importPath ] = decl
116
+ imports [ importPath ] = imports [ importPath ] || { }
109
117
110
118
tmpSymbols = symbols . split ( / \s + / ) . map ( s => {
111
119
if ( ! imports [ importPath ] [ s ] ) {
112
- imports [ importPath ] [ s ] = createImportedName ( s , importPath ) ;
120
+ imports [ importPath ] [ s ] = createImportedName ( s , importPath )
113
121
}
114
122
115
- return imports [ importPath ] [ s ] ;
116
- } ) ;
123
+ return imports [ importPath ] [ s ]
124
+ } )
117
125
}
118
126
119
- decl . value = tmpSymbols . join ( ' ' ) ;
127
+ decl . value = tmpSymbols . join ( ' ' )
120
128
}
121
- } ) ;
129
+ } )
122
130
123
- const importsOrder = topologicalSort ( graph , failOnWrongOrder ) ;
131
+ const importsOrder = topologicalSort ( graph , failOnWrongOrder )
124
132
125
133
if ( importsOrder instanceof Error ) {
126
- const importPath = importsOrder . nodes . find ( importPath => importDecls . hasOwnProperty ( importPath ) ) ;
127
- const decl = importDecls [ importPath ] ;
134
+ const importPath = importsOrder . nodes . find ( importPath =>
135
+ importDecls . hasOwnProperty ( importPath )
136
+ )
137
+ const decl = importDecls [ importPath ]
128
138
129
- const errMsg = 'Failed to resolve order of composed modules ' + serializeImports ( importsOrder . nodes ) + '.' ;
139
+ const errMsg =
140
+ 'Failed to resolve order of composed modules ' +
141
+ serializeImports ( importsOrder . nodes ) +
142
+ '.'
130
143
131
144
throw decl . error ( errMsg , {
132
145
plugin : 'modules-extract-imports' ,
133
- word : 'composes' ,
134
- } ) ;
146
+ word : 'composes'
147
+ } )
135
148
}
136
149
137
- let lastImportRule ;
150
+ let lastImportRule
138
151
importsOrder . forEach ( path => {
139
- const importedSymbols = imports [ path ] ;
140
- let rule = existingImports [ path ] ;
152
+ const importedSymbols = imports [ path ]
153
+ let rule = existingImports [ path ]
141
154
142
155
if ( ! rule && importedSymbols ) {
143
156
rule = postcss . rule ( {
144
157
selector : `:import("${ path } ")` ,
145
- raws : { after : '\n' } ,
146
- } ) ;
158
+ raws : { after : '\n' }
159
+ } )
147
160
148
- if ( lastImportRule )
149
- css . insertAfter ( lastImportRule , rule ) ;
150
- else
151
- css . prepend ( rule ) ;
161
+ if ( lastImportRule ) css . insertAfter ( lastImportRule , rule )
162
+ else css . prepend ( rule )
152
163
}
153
164
154
- lastImportRule = rule ;
165
+ lastImportRule = rule
155
166
156
- if ( ! importedSymbols ) return ;
167
+ if ( ! importedSymbols ) return
157
168
158
169
Object . keys ( importedSymbols ) . forEach ( importedSymbol => {
159
- rule . append ( postcss . decl ( {
160
- value : importedSymbol ,
161
- prop : importedSymbols [ importedSymbol ] ,
162
- raws : { before : '\n ' } ,
163
- } ) ) ;
164
- } ) ;
165
- } ) ;
166
- } ;
167
- } ) ;
168
-
169
- export default processor ;
170
+ rule . append (
171
+ postcss . decl ( {
172
+ value : importedSymbol ,
173
+ prop : importedSymbols [ importedSymbol ] ,
174
+ raws : { before : '\n ' }
175
+ } )
176
+ )
177
+ } )
178
+ } )
179
+ }
180
+ } )
0 commit comments