11const topologicalSort = require ( "./topologicalSort" ) ;
22
3- const declWhitelist = [ "composes" ] ;
4- const declFilter = new RegExp ( `^(${ declWhitelist . join ( "|" ) } )$` ) ;
53const matchImports = / ^ ( .+ ?) \s + f r o m \s + (?: " ( [ ^ " ] + ) " | ' ( [ ^ ' ] + ) ' | ( g l o b a l ) ) $ / ;
64const icssImport = / ^ : i m p o r t \( (?: " ( [ ^ " ] + ) " | ' ( [ ^ ' ] + ) ' ) \) / ;
75
86const VISITED_MARKER = 1 ;
97
10- function createParentName ( rule , root ) {
11- return `__${ root . index ( rule . parent ) } _${ rule . selector } ` ;
12- }
13-
14- function serializeImports ( imports ) {
15- return imports . map ( ( importPath ) => "`" + importPath + "`" ) . join ( ", " ) ;
16- }
17-
188/**
199 * :import('G') {}
2010 *
@@ -54,53 +44,53 @@ function addImportToGraph(importId, parentId, graph, visited) {
5444 }
5545
5646 visited [ visitedId ] = VISITED_MARKER ;
47+
5748 siblings . push ( importId ) ;
5849 }
5950}
6051
6152module . exports = ( options = { } ) => {
53+ let importIndex = 0 ;
54+ const createImportedName =
55+ typeof options . createImportedName !== "function"
56+ ? ( importName /*, path*/ ) =>
57+ `i__imported_${ importName . replace ( / \W / g, "_" ) } _${ importIndex ++ } `
58+ : options . createImportedName ;
6259 const failOnWrongOrder = options . failOnWrongOrder ;
6360
6461 return {
6562 postcssPlugin : "postcss-modules-extract-imports" ,
66- prepare ( result ) {
63+ prepare ( ) {
6764 const graph = { } ;
6865 const visited = { } ;
6966 const existingImports = { } ;
7067 const importDecls = { } ;
7168 const imports = { } ;
7269
73- let importIndex = 0 ;
74-
75- const createImportedName =
76- typeof options . createImportedName !== "function"
77- ? ( importName /*, path*/ ) =>
78- `i__imported_${ importName . replace ( / \W / g, "_" ) } _${ importIndex ++ } `
79- : options . createImportedName ;
80-
8170 return {
82- // Check the existing imports order and save refs
83- Rule ( rule ) {
84- const matches = icssImport . exec ( rule . selector ) ;
71+ OnceExit ( root , postcss ) {
72+ // Check the existing imports order and save refs
73+ root . walkRules ( ( rule ) => {
74+ const matches = icssImport . exec ( rule . selector ) ;
8575
86- if ( matches ) {
87- const [ , /*match*/ doubleQuotePath , singleQuotePath ] = matches ;
88- const importPath = doubleQuotePath || singleQuotePath ;
76+ if ( matches ) {
77+ const [ , /*match*/ doubleQuotePath , singleQuotePath ] = matches ;
78+ const importPath = doubleQuotePath || singleQuotePath ;
8979
90- addImportToGraph ( importPath , "root" , graph , visited ) ;
80+ addImportToGraph ( importPath , "root" , graph , visited ) ;
9181
92- existingImports [ importPath ] = rule ;
93- }
94- } ,
95- Declaration ( decl ) {
96- if ( ! declFilter . test ( decl . prop ) ) {
97- return ;
98- }
82+ existingImports [ importPath ] = rule ;
83+ }
84+ } ) ;
85+
86+ root . walkDecls ( / ^ c o m p o s e s $ / , ( declaration ) => {
87+ const matches = declaration . value . match ( matchImports ) ;
9988
100- let matches = decl . value . match ( matchImports ) ;
101- let tmpSymbols ;
89+ if ( ! matches ) {
90+ return ;
91+ }
10292
103- if ( matches ) {
93+ let tmpSymbols ;
10494 let [
10595 ,
10696 /*match*/ symbols ,
@@ -114,11 +104,22 @@ module.exports = (options = {}) => {
114104 tmpSymbols = symbols . split ( / \s + / ) . map ( ( s ) => `global(${ s } )` ) ;
115105 } else {
116106 const importPath = doubleQuotePath || singleQuotePath ;
117- const parentRule = createParentName ( decl . parent , result . root ) ;
107+
108+ let parent = declaration . parent ;
109+ let parentIndexes = "" ;
110+
111+ while ( parent . type !== "root" ) {
112+ parentIndexes =
113+ parent . parent . index ( parent ) + "_" + parentIndexes ;
114+ parent = parent . parent ;
115+ }
116+
117+ const { selector } = declaration . parent ;
118+ const parentRule = `_${ parentIndexes } ${ selector } ` ;
118119
119120 addImportToGraph ( importPath , parentRule , graph , visited ) ;
120121
121- importDecls [ importPath ] = decl ;
122+ importDecls [ importPath ] = declaration ;
122123 imports [ importPath ] = imports [ importPath ] || { } ;
123124
124125 tmpSymbols = symbols . split ( / \s + / ) . map ( ( s ) => {
@@ -130,10 +131,9 @@ module.exports = (options = {}) => {
130131 } ) ;
131132 }
132133
133- decl . value = tmpSymbols . join ( " " ) ;
134- }
135- } ,
136- OnceExit ( root , postcss ) {
134+ declaration . value = tmpSymbols . join ( " " ) ;
135+ } ) ;
136+
137137 const importsOrder = topologicalSort ( graph , failOnWrongOrder ) ;
138138
139139 if ( importsOrder instanceof Error ) {
@@ -143,15 +143,17 @@ module.exports = (options = {}) => {
143143 ) ;
144144 const decl = importDecls [ importPath ] ;
145145
146- const errMsg =
146+ throw decl . error (
147147 "Failed to resolve order of composed modules " +
148- serializeImports ( importsOrder . nodes ) +
149- "." ;
150-
151- throw decl . error ( errMsg , {
152- plugin : "postcss-modules-extract-imports" ,
153- word : "composes" ,
154- } ) ;
148+ importsOrder . nodes
149+ . map ( ( importPath ) => "`" + importPath + "`" )
150+ . join ( ", " ) +
151+ "." ,
152+ {
153+ plugin : "postcss-modules-extract-imports" ,
154+ word : "composes" ,
155+ }
156+ ) ;
155157 }
156158
157159 let lastImportRule ;
0 commit comments