@@ -96,76 +96,30 @@ export interface StylesheetLanguage {
96
96
const postcssProcessors = new Map < string , WeakRef < PostcssProcessor > > ( ) ;
97
97
98
98
export class StylesheetPluginFactory {
99
- private postcssProcessor ?: PostcssProcessor ;
100
-
101
99
constructor (
102
100
private readonly options : StylesheetPluginOptions ,
103
101
private readonly cache ?: LoadResultCache ,
104
102
) { }
105
103
106
104
create ( language : Readonly < StylesheetLanguage > ) : Plugin {
105
+ const { cache, options, setupPostcss } = this ;
106
+
107
107
// Return a noop plugin if no load actions are required
108
- if (
109
- ! language . process &&
110
- ! this . options . postcssConfiguration &&
111
- ! this . options . tailwindConfiguration
112
- ) {
108
+ if ( ! language . process && ! options . postcssConfiguration && ! options . tailwindConfiguration ) {
113
109
return {
114
110
name : 'angular-' + language . name ,
115
111
setup ( ) { } ,
116
112
} ;
117
113
}
118
114
119
- const { cache, options } = this ;
120
- const setupPostcss = async ( ) => {
121
- // Return already created processor if present
122
- if ( this . postcssProcessor ) {
123
- return this . postcssProcessor ;
124
- }
125
-
126
- if ( options . postcssConfiguration ) {
127
- const postCssInstanceKey = JSON . stringify ( options . postcssConfiguration ) ;
128
-
129
- this . postcssProcessor = postcssProcessors . get ( postCssInstanceKey ) ?. deref ( ) ;
130
-
131
- if ( ! this . postcssProcessor ) {
132
- postcss ??= ( await import ( 'postcss' ) ) . default ;
133
- this . postcssProcessor = postcss ( ) ;
134
-
135
- for ( const [ pluginName , pluginOptions ] of options . postcssConfiguration . plugins ) {
136
- const { default : plugin } = await import ( pluginName ) ;
137
- if ( typeof plugin !== 'function' || plugin . postcss !== true ) {
138
- throw new Error ( `Attempted to load invalid Postcss plugin: "${ pluginName } "` ) ;
139
- }
140
- this . postcssProcessor . use ( plugin ( pluginOptions ) ) ;
141
- }
142
-
143
- postcssProcessors . set ( postCssInstanceKey , new WeakRef ( this . postcssProcessor ) ) ;
144
- }
145
- } else if ( options . tailwindConfiguration ) {
146
- const { package : tailwindPackage , file : config } = options . tailwindConfiguration ;
147
- const postCssInstanceKey = tailwindPackage + ':' + config ;
148
- this . postcssProcessor = postcssProcessors . get ( postCssInstanceKey ) ?. deref ( ) ;
149
-
150
- if ( ! this . postcssProcessor ) {
151
- postcss ??= ( await import ( 'postcss' ) ) . default ;
152
- const tailwind = await import ( tailwindPackage ) ;
153
- this . postcssProcessor = postcss ( ) . use ( tailwind . default ( { config } ) ) ;
154
- postcssProcessors . set ( postCssInstanceKey , new WeakRef ( this . postcssProcessor ) ) ;
155
- }
156
- }
157
-
158
- return this . postcssProcessor ;
159
- } ;
160
-
161
115
return {
162
116
name : 'angular-' + language . name ,
163
117
async setup ( build ) {
164
118
// Setup postcss if needed
165
119
let postcssProcessor : PostcssProcessor | undefined ;
166
120
build . onStart ( async ( ) => {
167
121
try {
168
- postcssProcessor = await setupPostcss ( ) ;
122
+ postcssProcessor = await setupPostcss ;
169
123
} catch {
170
124
return {
171
125
errors : [
@@ -229,6 +183,56 @@ export class StylesheetPluginFactory {
229
183
} ,
230
184
} ;
231
185
}
186
+
187
+ private setupPostcssPromise : Promise < PostcssProcessor | undefined > | undefined ;
188
+ private get setupPostcss ( ) : Promise < PostcssProcessor | undefined > {
189
+ return ( this . setupPostcssPromise ??= this . initPostcss ( ) ) ;
190
+ }
191
+
192
+ private initPostcssCallCount = 0 ;
193
+ /**
194
+ * This method should not be called directly.
195
+ * Use {@link setupPostcss} instead.
196
+ */
197
+ private async initPostcss ( ) : Promise < PostcssProcessor | undefined > {
198
+ assert . equal ( ++ this . initPostcssCallCount , 1 , '`initPostcss` was called more than once.' ) ;
199
+
200
+ const { options } = this ;
201
+ if ( options . postcssConfiguration ) {
202
+ const postCssInstanceKey = JSON . stringify ( options . postcssConfiguration ) ;
203
+ let postcssProcessor = postcssProcessors . get ( postCssInstanceKey ) ?. deref ( ) ;
204
+
205
+ if ( ! postcssProcessor ) {
206
+ postcss ??= ( await import ( 'postcss' ) ) . default ;
207
+ postcssProcessor = postcss ( ) ;
208
+ for ( const [ pluginName , pluginOptions ] of options . postcssConfiguration . plugins ) {
209
+ const { default : plugin } = await import ( pluginName ) ;
210
+ if ( typeof plugin !== 'function' || plugin . postcss !== true ) {
211
+ throw new Error ( `Attempted to load invalid Postcss plugin: "${ pluginName } "` ) ;
212
+ }
213
+
214
+ postcssProcessor . use ( plugin ( pluginOptions ) ) ;
215
+ }
216
+
217
+ postcssProcessors . set ( postCssInstanceKey , new WeakRef ( postcssProcessor ) ) ;
218
+ }
219
+
220
+ return postcssProcessor ;
221
+ } else if ( options . tailwindConfiguration ) {
222
+ const { package : tailwindPackage , file : config } = options . tailwindConfiguration ;
223
+ const postCssInstanceKey = tailwindPackage + ':' + config ;
224
+ let postcssProcessor = postcssProcessors . get ( postCssInstanceKey ) ?. deref ( ) ;
225
+
226
+ if ( ! postcssProcessor ) {
227
+ postcss ??= ( await import ( 'postcss' ) ) . default ;
228
+ const tailwind = await import ( tailwindPackage ) ;
229
+ postcssProcessor = postcss ( ) . use ( tailwind . default ( { config } ) ) ;
230
+ postcssProcessors . set ( postCssInstanceKey , new WeakRef ( postcssProcessor ) ) ;
231
+ }
232
+
233
+ return postcssProcessor ;
234
+ }
235
+ }
232
236
}
233
237
234
238
async function processStylesheet (
0 commit comments