@@ -18,8 +18,6 @@ import {
1818} from './virtual_file_system_decorator' ;
1919import { resolveEntryModuleFromMain } from './entry_resolver' ;
2020import {
21- TransformOperation ,
22- makeTransform ,
2321 replaceBootstrap ,
2422 exportNgFactory ,
2523 exportLazyModuleMap ,
@@ -41,15 +39,14 @@ import {
4139 CompilerOptions ,
4240 CompilerHost ,
4341 Diagnostics ,
44- CustomTransformers ,
4542 EmitFlags ,
4643 LazyRoute ,
4744 createProgram ,
4845 createCompilerHost ,
4946 formatDiagnostics ,
5047 readConfiguration ,
5148} from './ngtools_api' ;
52- import { findAstNodes } from './transformers/ast_helpers' ;
49+ import { collectDeepNodes } from './transformers/ast_helpers' ;
5350
5451
5552/**
@@ -95,8 +92,9 @@ export class AngularCompilerPlugin implements Tapable {
9592 private _lazyRoutes : LazyRouteMap = Object . create ( null ) ;
9693 private _tsConfigPath : string ;
9794 private _entryModule : string ;
95+ private _mainPath : string | undefined ;
9896 private _basePath : string ;
99- private _transformMap : Map < string , TransformOperation [ ] > = new Map ( ) ;
97+ private _transformers : ts . TransformerFactory < ts . SourceFile > [ ] = [ ] ;
10098 private _platform : PLATFORM ;
10199 private _JitMode = false ;
102100 private _emitSkipped = true ;
@@ -128,6 +126,9 @@ export class AngularCompilerPlugin implements Tapable {
128126 get options ( ) { return this . _options ; }
129127 get done ( ) { return this . _donePromise ; }
130128 get entryModule ( ) {
129+ if ( ! this . _entryModule ) {
130+ return undefined ;
131+ }
131132 const splitted = this . _entryModule . split ( '#' ) ;
132133 const path = splitted [ 0 ] ;
133134 const className = splitted [ 1 ] || 'default' ;
@@ -157,6 +158,7 @@ export class AngularCompilerPlugin implements Tapable {
157158 basePath = path . resolve ( process . cwd ( ) , options . basePath ) ;
158159 }
159160
161+ // TODO: check if we can get this from readConfiguration
160162 this . _basePath = basePath ;
161163
162164 // Parse the tsconfig contents.
@@ -224,15 +226,6 @@ export class AngularCompilerPlugin implements Tapable {
224226 options . missingTranslation as 'error' | 'warning' | 'ignore' ;
225227 }
226228
227- // Use entryModule if available in options, otherwise resolve it from mainPath after program
228- // creation.
229- if ( this . _options . entryModule ) {
230- this . _entryModule = this . _options . entryModule ;
231- } else if ( this . _compilerOptions . entryModule ) {
232- this . _entryModule = path . resolve ( this . _basePath ,
233- this . _compilerOptions . entryModule ) ;
234- }
235-
236229 // Create the webpack compiler host.
237230 const webpackCompilerHost = new WebpackCompilerHost ( this . _compilerOptions , this . _basePath ) ;
238231 webpackCompilerHost . enableCaching ( ) ;
@@ -266,8 +259,26 @@ export class AngularCompilerPlugin implements Tapable {
266259 // Use an identity function as all our paths are absolute already.
267260 this . _moduleResolutionCache = ts . createModuleResolutionCache ( this . _basePath , x => x ) ;
268261
262+ // Resolve mainPath if provided.
263+ if ( options . mainPath ) {
264+ this . _mainPath = this . _compilerHost . resolve ( options . mainPath ) ;
265+ }
266+
267+ // Use entryModule if available in options, otherwise resolve it from mainPath after program
268+ // creation.
269+ if ( this . _options . entryModule ) {
270+ this . _entryModule = this . _options . entryModule ;
271+ } else if ( this . _compilerOptions . entryModule ) {
272+ this . _entryModule = path . resolve ( this . _basePath ,
273+ this . _compilerOptions . entryModule ) ;
274+ }
275+
269276 // Set platform.
270277 this . _platform = options . platform || PLATFORM . Browser ;
278+
279+ // Make transformers.
280+ this . _makeTransformers ( ) ;
281+
271282 timeEnd ( 'AngularCompilerPlugin._setupOptions' ) ;
272283 }
273284
@@ -332,11 +343,10 @@ export class AngularCompilerPlugin implements Tapable {
332343 } )
333344 . then ( ( ) => {
334345 // If there's still no entryModule try to resolve from mainPath.
335- if ( ! this . _entryModule && this . _options . mainPath ) {
346+ if ( ! this . _entryModule && this . _mainPath ) {
336347 time ( 'AngularCompilerPlugin._make.resolveEntryModuleFromMain' ) ;
337- const mainPath = path . resolve ( this . _basePath , this . _options . mainPath ) ;
338348 this . _entryModule = resolveEntryModuleFromMain (
339- mainPath , this . _compilerHost , this . _getTsProgram ( ) ) ;
349+ this . _mainPath , this . _compilerHost , this . _getTsProgram ( ) ) ;
340350 timeEnd ( 'AngularCompilerPlugin._make.resolveEntryModuleFromMain' ) ;
341351 }
342352 } ) ;
@@ -633,6 +643,41 @@ export class AngularCompilerPlugin implements Tapable {
633643 } ) ;
634644 }
635645
646+ private _makeTransformers ( ) {
647+
648+ // TODO use compilerhost.denormalize when #8210 is merged.
649+ const isAppPath = ( fileName : string ) =>
650+ this . _rootNames . includes ( fileName . replace ( / \/ / g, path . sep ) ) ;
651+ const isMainPath = ( fileName : string ) => fileName === this . _mainPath ;
652+ const getEntryModule = ( ) => this . entryModule ;
653+ const getLazyRoutes = ( ) => this . _lazyRoutes ;
654+
655+ if ( this . _JitMode ) {
656+ // Replace resources in JIT.
657+ this . _transformers . push ( replaceResources ( isAppPath ) ) ;
658+ }
659+
660+ if ( this . _platform === PLATFORM . Browser ) {
661+ // If we have a locale, auto import the locale data file.
662+ // This transform must go before replaceBootstrap because it looks for the entry module
663+ // import, which will be replaced.
664+ if ( this . _compilerOptions . i18nInLocale ) {
665+ this . _transformers . push ( registerLocaleData ( isAppPath , getEntryModule ,
666+ this . _compilerOptions . i18nInLocale ) ) ;
667+ }
668+
669+ if ( ! this . _JitMode ) {
670+ // Replace bootstrap in browser AOT.
671+ this . _transformers . push ( replaceBootstrap ( isAppPath , getEntryModule ) ) ;
672+ }
673+ } else if ( this . _platform === PLATFORM . Server ) {
674+ this . _transformers . push ( exportLazyModuleMap ( isMainPath , getLazyRoutes ) ) ;
675+ if ( ! this . _JitMode ) {
676+ this . _transformers . push ( exportNgFactory ( isMainPath , getEntryModule ) ) ;
677+ }
678+ }
679+ }
680+
636681 private _update ( ) {
637682 time ( 'AngularCompilerPlugin._update' ) ;
638683 // We only want to update on TS and template changes, but all kinds of files are on this
@@ -662,7 +707,7 @@ export class AngularCompilerPlugin implements Tapable {
662707 }
663708 } )
664709 . then ( ( ) => {
665- // Build transforms, emit and report errors.
710+ // Emit and report errors.
666711
667712 // We now have the final list of changed TS files.
668713 // Go through each changed file and add transforms as needed.
@@ -677,56 +722,9 @@ export class AngularCompilerPlugin implements Tapable {
677722 return sourceFile ;
678723 } ) ;
679724
680- time ( 'AngularCompilerPlugin._update.transformOps' ) ;
681- sourceFiles . forEach ( ( sf ) => {
682- const fileName = this . _compilerHost . resolve ( sf . fileName ) ;
683- let transformOps = [ ] ;
684-
685- if ( this . _JitMode ) {
686- transformOps . push ( ...replaceResources ( sf ) ) ;
687- }
688-
689- if ( this . _platform === PLATFORM . Browser ) {
690- if ( ! this . _JitMode ) {
691- transformOps . push ( ...replaceBootstrap ( sf , this . entryModule ) ) ;
692- }
693-
694- // If we have a locale, auto import the locale data file.
695- if ( this . _compilerOptions . i18nInLocale ) {
696- transformOps . push ( ...registerLocaleData (
697- sf ,
698- this . entryModule ,
699- this . _compilerOptions . i18nInLocale
700- ) ) ;
701- }
702- } else if ( this . _platform === PLATFORM . Server ) {
703- if ( fileName === this . _compilerHost . resolve ( this . _options . mainPath ) ) {
704- transformOps . push ( ...exportLazyModuleMap ( sf , this . _lazyRoutes ) ) ;
705- if ( ! this . _JitMode ) {
706- transformOps . push ( ...exportNgFactory ( sf , this . entryModule ) ) ;
707- }
708- }
709- }
710-
711- // We need to keep a map of transforms for each file, to reapply on each update.
712- this . _transformMap . set ( fileName , transformOps ) ;
713- } ) ;
714-
715- const transformOps : TransformOperation [ ] = [ ] ;
716- for ( let fileTransformOps of this . _transformMap . values ( ) ) {
717- transformOps . push ( ...fileTransformOps ) ;
718- }
719- timeEnd ( 'AngularCompilerPlugin._update.transformOps' ) ;
720-
721- time ( 'AngularCompilerPlugin._update.makeTransform' ) ;
722- const transformers : CustomTransformers = {
723- beforeTs : transformOps . length > 0 ? [ makeTransform ( transformOps ) ] : [ ]
724- } ;
725- timeEnd ( 'AngularCompilerPlugin._update.makeTransform' ) ;
726-
727725 // Emit files.
728726 time ( 'AngularCompilerPlugin._update._emit' ) ;
729- const { emitResult, diagnostics } = this . _emit ( sourceFiles , transformers ) ;
727+ const { emitResult, diagnostics } = this . _emit ( sourceFiles ) ;
730728 timeEnd ( 'AngularCompilerPlugin._update._emit' ) ;
731729
732730 // Report diagnostics.
@@ -826,7 +824,7 @@ export class AngularCompilerPlugin implements Tapable {
826824 const host = this . _compilerHost ;
827825 const cache = this . _moduleResolutionCache ;
828826
829- const esImports = findAstNodes < ts . ImportDeclaration > ( null , sourceFile ,
827+ const esImports = collectDeepNodes < ts . ImportDeclaration > ( sourceFile ,
830828 ts . SyntaxKind . ImportDeclaration )
831829 . map ( decl => {
832830 const moduleName = ( decl . moduleSpecifier as ts . StringLiteral ) . text ;
@@ -858,10 +856,7 @@ export class AngularCompilerPlugin implements Tapable {
858856 // This code mostly comes from `performCompilation` in `@angular/compiler-cli`.
859857 // It skips the program creation because we need to use `loadNgStructureAsync()`,
860858 // and uses CustomTransformers.
861- private _emit (
862- sourceFiles : ts . SourceFile [ ] ,
863- customTransformers : ts . CustomTransformers & CustomTransformers
864- ) {
859+ private _emit ( sourceFiles : ts . SourceFile [ ] ) {
865860 time ( 'AngularCompilerPlugin._emit' ) ;
866861 const program = this . _program ;
867862 const allDiagnostics : Diagnostics = [ ] ;
@@ -888,7 +883,7 @@ export class AngularCompilerPlugin implements Tapable {
888883 const timeLabel = `AngularCompilerPlugin._emit.ts+${ sf . fileName } +.emit` ;
889884 time ( timeLabel ) ;
890885 emitResult = tsProgram . emit ( sf , undefined , undefined , undefined ,
891- { before : customTransformers . beforeTs }
886+ { before : this . _transformers }
892887 ) ;
893888 allDiagnostics . push ( ...emitResult . diagnostics ) ;
894889 timeEnd ( timeLabel ) ;
@@ -923,7 +918,11 @@ export class AngularCompilerPlugin implements Tapable {
923918 time ( 'AngularCompilerPlugin._emit.ng.emit' ) ;
924919 const extractI18n = ! ! this . _compilerOptions . i18nOutFile ;
925920 const emitFlags = extractI18n ? EmitFlags . I18nBundle : EmitFlags . Default ;
926- emitResult = angularProgram . emit ( { emitFlags, customTransformers } ) ;
921+ emitResult = angularProgram . emit ( {
922+ emitFlags, customTransformers : {
923+ beforeTs : this . _transformers
924+ }
925+ } ) ;
927926 allDiagnostics . push ( ...emitResult . diagnostics ) ;
928927 if ( extractI18n ) {
929928 this . writeI18nOutFile ( ) ;
0 commit comments