@@ -160,37 +160,6 @@ export function createCompilerPlugin(
160
160
build . initialOptions . define [ key ] = value . toString ( ) ;
161
161
}
162
162
163
- // The tsconfig is loaded in setup instead of in start to allow the esbuild target build option to be modified.
164
- // esbuild build options can only be modified in setup prior to starting the build.
165
- const {
166
- options : compilerOptions ,
167
- rootNames,
168
- errors : configurationDiagnostics ,
169
- } = compilerCli . readConfiguration ( pluginOptions . tsconfig , {
170
- noEmitOnError : false ,
171
- suppressOutputPathCheck : true ,
172
- outDir : undefined ,
173
- inlineSources : pluginOptions . sourcemap ,
174
- inlineSourceMap : pluginOptions . sourcemap ,
175
- sourceMap : false ,
176
- mapRoot : undefined ,
177
- sourceRoot : undefined ,
178
- declaration : false ,
179
- declarationMap : false ,
180
- allowEmptyCodegenFiles : false ,
181
- annotationsAs : 'decorators' ,
182
- enableResourceInlining : false ,
183
- } ) ;
184
-
185
- if ( compilerOptions . target === undefined || compilerOptions . target < ts . ScriptTarget . ES2022 ) {
186
- // If 'useDefineForClassFields' is already defined in the users project leave the value as is.
187
- // Otherwise fallback to false due to https://github.com/microsoft/TypeScript/issues/45995
188
- // which breaks the deprecated `@Effects` NGRX decorator and potentially other existing code as well.
189
- compilerOptions . target = ts . ScriptTarget . ES2022 ;
190
- compilerOptions . useDefineForClassFields ??= false ;
191
- // TODO: show warning about this override when we have access to the logger.
192
- }
193
-
194
163
// The file emitter created during `onStart` that will be used during the build in `onLoad` callbacks for TS files
195
164
let fileEmitter : FileEmitter | undefined ;
196
165
@@ -203,6 +172,52 @@ export function createCompilerPlugin(
203
172
// Reset stylesheet resource output files
204
173
stylesheetResourceFiles = [ ] ;
205
174
175
+ // The tsconfig is loaded in setup instead of in start to allow the esbuild target build option to be modified.
176
+ // esbuild build options can only be modified in setup prior to starting the build.
177
+ const {
178
+ options : compilerOptions ,
179
+ rootNames,
180
+ errors : configurationDiagnostics ,
181
+ } = compilerCli . readConfiguration ( pluginOptions . tsconfig , {
182
+ noEmitOnError : false ,
183
+ suppressOutputPathCheck : true ,
184
+ outDir : undefined ,
185
+ inlineSources : pluginOptions . sourcemap ,
186
+ inlineSourceMap : pluginOptions . sourcemap ,
187
+ sourceMap : false ,
188
+ mapRoot : undefined ,
189
+ sourceRoot : undefined ,
190
+ declaration : false ,
191
+ declarationMap : false ,
192
+ allowEmptyCodegenFiles : false ,
193
+ annotationsAs : 'decorators' ,
194
+ enableResourceInlining : false ,
195
+ } ) ;
196
+
197
+ if (
198
+ compilerOptions . target === undefined ||
199
+ compilerOptions . target < ts . ScriptTarget . ES2022
200
+ ) {
201
+ // If 'useDefineForClassFields' is already defined in the users project leave the value as is.
202
+ // Otherwise fallback to false due to https://github.com/microsoft/TypeScript/issues/45995
203
+ // which breaks the deprecated `@Effects` NGRX decorator and potentially other existing code as well.
204
+ compilerOptions . target = ts . ScriptTarget . ES2022 ;
205
+ compilerOptions . useDefineForClassFields ??= false ;
206
+
207
+ ( result . warnings ??= [ ] ) . push ( {
208
+ text :
209
+ 'TypeScript compiler options "target" and "useDefineForClassFields" are set to "ES2022" and ' +
210
+ '"false" respectively by the Angular CLI.' ,
211
+ location : { file : pluginOptions . tsconfig } ,
212
+ notes : [
213
+ {
214
+ text : `To control ECMA version and features use the Browerslist configuration. ' +
215
+ 'For more information, see https://github.com/browserslist/browsers§list'` ,
216
+ } ,
217
+ ] ,
218
+ } ) ;
219
+ }
220
+
206
221
// Create TypeScript compiler host
207
222
const host = ts . createIncrementalCompilerHost ( compilerOptions ) ;
208
223
@@ -316,80 +331,74 @@ export function createCompilerPlugin(
316
331
return result ;
317
332
} ) ;
318
333
319
- build . onLoad (
320
- { filter : compilerOptions . allowJs ? / \. [ c m ] ? [ j t ] s x ? $ / : / \. [ c m ] ? t s x ? $ / } ,
321
- async ( args ) => {
322
- assert . ok ( fileEmitter , 'Invalid plugin execution order' ) ;
334
+ build . onLoad ( { filter : / \. [ c m ] ? [ j t ] s x ? $ / } , async ( args ) => {
335
+ assert . ok ( fileEmitter , 'Invalid plugin execution order' ) ;
323
336
324
- const typescriptResult = await fileEmitter (
325
- pluginOptions . fileReplacements ?. [ args . path ] ?? args . path ,
326
- ) ;
327
- if ( ! typescriptResult ) {
328
- // No TS result indicates the file is not part of the TypeScript program.
329
- // If allowJs is enabled and the file is JS then defer to the next load hook.
330
- if ( compilerOptions . allowJs && / \. [ c m ] ? j s $ / . test ( args . path ) ) {
331
- return undefined ;
332
- }
333
-
334
- // Otherwise return an error
335
- return {
336
- errors : [
337
- {
338
- text : 'File is missing from the TypeScript compilation.' ,
339
- location : { file : args . path } ,
340
- notes : [
341
- {
342
- text : `Ensure the file is part of the TypeScript program via the 'files' or 'include' property.` ,
343
- } ,
344
- ] ,
345
- } ,
346
- ] ,
347
- } ;
348
- }
349
-
350
- const data = typescriptResult . content ?? '' ;
351
- const forceAsyncTransformation = / a s y n c \s + f u n c t i o n \s * \* / . test ( data ) ;
352
- const useInputSourcemap =
353
- pluginOptions . sourcemap &&
354
- ( ! ! pluginOptions . thirdPartySourcemaps || ! / [ \\ / ] n o d e _ m o d u l e s [ \\ / ] / . test ( args . path ) ) ;
355
-
356
- // If no additional transformations are needed, return the TypeScript output directly
357
- if ( ! forceAsyncTransformation && ! pluginOptions . advancedOptimizations ) {
358
- return {
359
- // Strip sourcemaps if they should not be used
360
- contents : useInputSourcemap
361
- ? data
362
- : data . replace ( / ^ \/ \/ # s o u r c e M a p p i n g U R L = [ ^ \r \n ] * / gm, '' ) ,
363
- loader : 'js' ,
364
- } ;
365
- }
337
+ const typescriptResult = await fileEmitter (
338
+ pluginOptions . fileReplacements ?. [ args . path ] ?? args . path ,
339
+ ) ;
340
+ if ( ! typescriptResult ) {
341
+ // No TS result indicates the file is not part of the TypeScript program.
342
+ // Otherwise return an error
343
+ return / \. [ c m ] ? j s $ / . test ( args . path )
344
+ ? undefined
345
+ : {
346
+ errors : [
347
+ {
348
+ text : 'File is missing from the TypeScript compilation.' ,
349
+ location : { file : args . path } ,
350
+ notes : [
351
+ {
352
+ text : `Ensure the file is part of the TypeScript program via the 'files' or 'include' property.` ,
353
+ } ,
354
+ ] ,
355
+ } ,
356
+ ] ,
357
+ } ;
358
+ }
366
359
367
- const babelResult = await transformAsync ( data , {
368
- filename : args . path ,
369
- inputSourceMap : ( useInputSourcemap ? undefined : false ) as undefined ,
370
- sourceMaps : pluginOptions . sourcemap ? 'inline' : false ,
371
- compact : false ,
372
- configFile : false ,
373
- babelrc : false ,
374
- browserslistConfigFile : false ,
375
- plugins : [ ] ,
376
- presets : [
377
- [
378
- angularApplicationPreset ,
379
- {
380
- forceAsyncTransformation,
381
- optimize : pluginOptions . advancedOptimizations && { } ,
382
- } ,
383
- ] ,
384
- ] ,
385
- } ) ;
360
+ const data = typescriptResult . content ?? '' ;
361
+ const forceAsyncTransformation = / a s y n c \s + f u n c t i o n \s * \* / . test ( data ) ;
362
+ const useInputSourcemap =
363
+ pluginOptions . sourcemap &&
364
+ ( ! ! pluginOptions . thirdPartySourcemaps || ! / [ \\ / ] n o d e _ m o d u l e s [ \\ / ] / . test ( args . path ) ) ;
386
365
366
+ // If no additional transformations are needed, return the TypeScript output directly
367
+ if ( ! forceAsyncTransformation && ! pluginOptions . advancedOptimizations ) {
387
368
return {
388
- contents : babelResult ?. code ?? '' ,
369
+ // Strip sourcemaps if they should not be used
370
+ contents : useInputSourcemap
371
+ ? data
372
+ : data . replace ( / ^ \/ \/ # s o u r c e M a p p i n g U R L = [ ^ \r \n ] * / gm, '' ) ,
389
373
loader : 'js' ,
390
374
} ;
391
- } ,
392
- ) ;
375
+ }
376
+
377
+ const babelResult = await transformAsync ( data , {
378
+ filename : args . path ,
379
+ inputSourceMap : ( useInputSourcemap ? undefined : false ) as undefined ,
380
+ sourceMaps : pluginOptions . sourcemap ? 'inline' : false ,
381
+ compact : false ,
382
+ configFile : false ,
383
+ babelrc : false ,
384
+ browserslistConfigFile : false ,
385
+ plugins : [ ] ,
386
+ presets : [
387
+ [
388
+ angularApplicationPreset ,
389
+ {
390
+ forceAsyncTransformation,
391
+ optimize : pluginOptions . advancedOptimizations && { } ,
392
+ } ,
393
+ ] ,
394
+ ] ,
395
+ } ) ;
396
+
397
+ return {
398
+ contents : babelResult ?. code ?? '' ,
399
+ loader : 'js' ,
400
+ } ;
401
+ } ) ;
393
402
394
403
build . onLoad ( { filter : / \. [ c m ] ? j s $ / } , async ( args ) => {
395
404
const data = await fs . readFile ( args . path , 'utf-8' ) ;
0 commit comments