5
5
* Use of this source code is governed by an MIT-style license that can be
6
6
* found in the LICENSE file at https://angular.io/license
7
7
*/
8
- // TODO: fix webpack typings.
9
- // tslint:disable-next-line:no-global-tslint-disable
10
- // tslint:disable:no-any
11
8
import { dirname , normalize , resolve , virtualFs } from '@angular-devkit/core' ;
12
9
import { ChildProcess , ForkOptions , fork } from 'child_process' ;
13
10
import * as fs from 'fs' ;
14
11
import * as path from 'path' ;
15
12
import * as ts from 'typescript' ;
13
+ import { Compiler , compilation } from 'webpack' ;
16
14
import { time , timeEnd } from './benchmark' ;
17
15
import { WebpackCompilerHost , workaroundResolve } from './compiler_host' ;
18
16
import { resolveEntryModuleFromMain } from './entry_resolver' ;
@@ -53,6 +51,12 @@ import {
53
51
VirtualFileSystemDecorator ,
54
52
VirtualWatchFileSystemDecorator ,
55
53
} from './virtual_file_system_decorator' ;
54
+ import {
55
+ Callback ,
56
+ InputFileSystem ,
57
+ NodeWatchFileSystemInterface ,
58
+ NormalModuleFactoryRequest ,
59
+ } from './webpack' ;
56
60
57
61
const treeKill = require ( 'tree-kill' ) ;
58
62
@@ -598,18 +602,28 @@ export class AngularCompilerPlugin {
598
602
}
599
603
600
604
// Registration hook for webpack plugin.
601
- // tslint:disable-next-line:no-any
602
- apply ( compiler : any ) {
605
+ apply ( compiler : Compiler ) {
603
606
// Decorate inputFileSystem to serve contents of CompilerHost.
604
607
// Use decorated inputFileSystem in watchFileSystem.
605
608
compiler . hooks . environment . tap ( 'angular-compiler' , ( ) => {
606
- compiler . inputFileSystem = new VirtualFileSystemDecorator (
607
- compiler . inputFileSystem , this . _compilerHost ) ;
608
- compiler . watchFileSystem = new VirtualWatchFileSystemDecorator ( compiler . inputFileSystem ) ;
609
+ // The webpack types currently do not include these
610
+ const compilerWithFileSystems = compiler as Compiler & {
611
+ inputFileSystem : InputFileSystem ,
612
+ watchFileSystem : NodeWatchFileSystemInterface ,
613
+ } ;
614
+
615
+ const inputDecorator = new VirtualFileSystemDecorator (
616
+ compilerWithFileSystems . inputFileSystem ,
617
+ this . _compilerHost ,
618
+ ) ;
619
+ compilerWithFileSystems . inputFileSystem = inputDecorator ;
620
+ compilerWithFileSystems . watchFileSystem = new VirtualWatchFileSystemDecorator (
621
+ inputDecorator ,
622
+ ) ;
609
623
} ) ;
610
624
611
625
// Add lazy modules to the context module for @angular /core
612
- compiler . hooks . contextModuleFactory . tap ( 'angular-compiler' , ( cmf : any ) => {
626
+ compiler . hooks . contextModuleFactory . tap ( 'angular-compiler' , cmf => {
613
627
const angularCorePackagePath = require . resolve ( '@angular/core/package.json' ) ;
614
628
615
629
// APFv6 does not have single FESM anymore. Instead of verifying if we're pointing to
@@ -621,141 +635,139 @@ export class AngularCompilerPlugin {
621
635
// We resolve any symbolic links in order to get the real path that would be used in webpack.
622
636
const angularCoreDirname = fs . realpathSync ( path . dirname ( angularCorePackagePath ) ) ;
623
637
624
- cmf . hooks . afterResolve . tapAsync ( 'angular-compiler' ,
625
- // tslint:disable-next-line:no-any
626
- ( result : any , callback : ( err ?: Error , request ?: any ) => void ) => {
627
- if ( ! result ) {
628
- return callback ( ) ;
629
- }
630
-
638
+ cmf . hooks . afterResolve . tapPromise ( 'angular-compiler' , async result => {
631
639
// Alter only request from Angular.
632
- if ( ! result . resource . startsWith ( angularCoreDirname ) ) {
633
- return callback ( undefined , result ) ;
634
- }
635
- if ( ! this . done ) {
636
- return callback ( undefined , result ) ;
640
+ if ( ! result || ! this . done || ! result . resource . startsWith ( angularCoreDirname ) ) {
641
+ return result ;
637
642
}
638
643
639
- this . done . then ( ( ) => {
640
- // This folder does not exist, but we need to give webpack a resource.
641
- // TODO: check if we can't just leave it as is (angularCoreModuleDir) .
642
- result . resource = path . join ( this . _basePath , '$$_lazy_route_resource' ) ;
643
- result . dependencies . forEach ( ( d : any ) => d . critical = false ) ;
644
- result . resolveDependencies = ( _fs : any , resourceOrOptions : any , recursiveOrCallback : any ,
645
- _regExp : RegExp , cb : any ) => {
646
- const dependencies = Object . keys ( this . _lazyRoutes )
647
- . map ( ( key ) => {
648
- const modulePath = this . _lazyRoutes [ key ] ;
649
- const importPath = key . split ( '#' ) [ 0 ] ;
650
- if ( modulePath !== null ) {
651
- const name = importPath . replace ( / ( \. n g f a c t o r y ) ? \. ( j s | t s ) $ / , '' ) ;
652
-
653
- return new this . _contextElementDependencyConstructor ( modulePath , name ) ;
654
- } else {
655
- return null ;
656
- }
657
- } )
658
- . filter ( x => ! ! x ) ;
659
- if ( typeof cb !== 'function' && typeof recursiveOrCallback === 'function' ) {
660
- // Webpack 4 only has 3 parameters
661
- cb = recursiveOrCallback ;
644
+ return this . done . then (
645
+ ( ) => {
646
+ // This folder does not exist, but we need to give webpack a resource .
647
+ // TODO: check if we can't just leave it as is (angularCoreModuleDir).
648
+ result . resource = path . join ( this . _basePath , '$$_lazy_route_resource' ) ;
649
+ // tslint:disable-next-line:no- any
650
+ result . dependencies . forEach ( ( d : any ) => d . critical = false ) ;
651
+ // tslint:disable-next-line:no-any
652
+ result . resolveDependencies = ( _fs : any , options : any , callback : Callback ) => {
653
+ const dependencies = Object . keys ( this . _lazyRoutes )
654
+ . map ( ( key ) => {
655
+ const modulePath = this . _lazyRoutes [ key ] ;
656
+ const importPath = key . split ( '#' ) [ 0 ] ;
657
+ if ( modulePath !== null ) {
658
+ const name = importPath . replace ( / ( \. n g f a c t o r y ) ? \. ( j s | t s ) $ / , '' ) ;
659
+
660
+ return new this . _contextElementDependencyConstructor ( modulePath , name ) ;
661
+ } else {
662
+ return null ;
663
+ }
664
+ } )
665
+ . filter ( x => ! ! x ) ;
666
+
662
667
if ( this . _options . nameLazyFiles ) {
663
- resourceOrOptions . chunkName = '[request]' ;
668
+ options . chunkName = '[request]' ;
664
669
}
665
- }
666
- cb ( null , dependencies ) ;
667
- } ;
668
670
669
- return callback ( undefined , result ) ;
670
- } , ( ) => callback ( ) )
671
- . catch ( err => callback ( err ) ) ;
671
+ callback ( null , dependencies ) ;
672
+ } ;
673
+
674
+ return result ;
675
+ } ,
676
+ ( ) => undefined ,
677
+ ) ;
672
678
} ) ;
673
679
} ) ;
674
680
675
681
// Create and destroy forked type checker on watch mode.
676
- compiler . hooks . watchRun . tapAsync ( 'angular-compiler' , ( _compiler : any , callback : any ) => {
682
+ compiler . hooks . watchRun . tap ( 'angular-compiler' , ( ) => {
677
683
if ( this . _forkTypeChecker && ! this . _typeCheckerProcess ) {
678
684
this . _createForkedTypeChecker ( ) ;
679
685
}
680
- callback ( ) ;
681
686
} ) ;
682
687
compiler . hooks . watchClose . tap ( 'angular-compiler' , ( ) => this . _killForkedTypeChecker ( ) ) ;
683
688
684
689
// Remake the plugin on each compilation.
685
- compiler . hooks . make . tapAsync (
686
- 'angular-compiler' ,
687
- ( compilation : any , cb : any ) => this . _make ( compilation , cb ) ,
688
- ) ;
690
+ compiler . hooks . make . tapPromise ( 'angular-compiler' , compilation => this . _make ( compilation ) ) ;
689
691
compiler . hooks . invalid . tap ( 'angular-compiler' , ( ) => this . _firstRun = false ) ;
690
- compiler . hooks . afterEmit . tapAsync ( 'angular-compiler' , ( compilation : any , cb : any ) => {
691
- compilation . _ngToolsWebpackPluginInstance = null ;
692
- cb ( ) ;
692
+ compiler . hooks . afterEmit . tap ( 'angular-compiler' , compilation => {
693
+ // tslint:disable-next-line:no-any
694
+ ( compilation as any ) . _ngToolsWebpackPluginInstance = null ;
693
695
} ) ;
694
696
compiler . hooks . done . tap ( 'angular-compiler' , ( ) => {
695
697
this . _donePromise = null ;
696
698
} ) ;
697
699
698
- compiler . hooks . afterResolvers . tap ( 'angular-compiler' , ( compiler : any ) => {
699
- compiler . hooks . normalModuleFactory . tap ( 'angular-compiler' , ( nmf : any ) => {
700
+ compiler . hooks . afterResolvers . tap ( 'angular-compiler' , compiler => {
701
+ compiler . hooks . normalModuleFactory . tap ( 'angular-compiler' , nmf => {
700
702
// Virtual file system.
701
703
// TODO: consider if it's better to remove this plugin and instead make it wait on the
702
704
// VirtualFileSystemDecorator.
703
705
// Wait for the plugin to be done when requesting `.ts` files directly (entry points), or
704
706
// when the issuer is a `.ts` or `.ngfactory.js` file.
705
- nmf . hooks . beforeResolve . tapAsync ( 'angular-compiler' , ( request : any , callback : any ) => {
706
- if ( this . done
707
- && ( request && ( request . request . endsWith ( '.ts' ) || request . request . endsWith ( '.tsx' ) )
708
- || ( request && request . context . issuer
709
- && / \. t s | n g f a c t o r y \. j s $ / . test ( request . context . issuer ) ) ) ) {
710
- this . done . then ( ( ) => callback ( null , request ) , ( ) => callback ( null , request ) ) ;
711
- } else {
712
- callback ( null , request ) ;
713
- }
714
- } ) ;
715
- } ) ;
716
- } ) ;
707
+ nmf . hooks . beforeResolve . tapPromise (
708
+ 'angular-compiler' ,
709
+ async ( request ?: NormalModuleFactoryRequest ) => {
710
+ if ( this . done && request ) {
711
+ const name = request . request ;
712
+ const issuer = request . contextInfo . issuer ;
713
+ if ( name . endsWith ( '.ts' ) || name . endsWith ( '.tsx' )
714
+ || ( issuer && / \. t s | n g f a c t o r y \. j s $ / . test ( issuer ) ) ) {
715
+ try {
716
+ await this . done ;
717
+ } catch { }
718
+ }
719
+ }
717
720
718
- compiler . hooks . normalModuleFactory . tap ( 'angular-compiler' , ( nmf : any ) => {
719
- nmf . hooks . beforeResolve . tapAsync ( 'angular-compiler' , ( request : any , callback : any ) => {
720
- resolveWithPaths (
721
- request ,
722
- callback ,
723
- this . _compilerOptions ,
724
- this . _compilerHost ,
725
- this . _moduleResolutionCache ,
721
+ return request ;
722
+ } ,
726
723
) ;
727
724
} ) ;
728
725
} ) ;
726
+
727
+ compiler . hooks . normalModuleFactory . tap ( 'angular-compiler' , nmf => {
728
+ nmf . hooks . beforeResolve . tapAsync (
729
+ 'angular-compiler' ,
730
+ ( request : NormalModuleFactoryRequest , callback : Callback < NormalModuleFactoryRequest > ) => {
731
+ resolveWithPaths (
732
+ request ,
733
+ callback ,
734
+ this . _compilerOptions ,
735
+ this . _compilerHost ,
736
+ this . _moduleResolutionCache ,
737
+ ) ;
738
+ } ,
739
+ ) ;
740
+ } ) ;
729
741
}
730
742
731
- private _make ( compilation : any , cb : ( err ?: any , request ?: any ) => void ) {
743
+ private async _make ( compilation : compilation . Compilation ) {
732
744
time ( 'AngularCompilerPlugin._make' ) ;
733
745
this . _emitSkipped = true ;
734
- if ( compilation . _ngToolsWebpackPluginInstance ) {
735
- return cb ( new Error ( 'An @ngtools/webpack plugin already exist for this compilation.' ) ) ;
746
+ // tslint:disable-next-line:no-any
747
+ if ( ( compilation as any ) . _ngToolsWebpackPluginInstance ) {
748
+ throw new Error ( 'An @ngtools/webpack plugin already exist for this compilation.' ) ;
736
749
}
737
750
738
751
// Set a private variable for this plugin instance.
739
- compilation . _ngToolsWebpackPluginInstance = this ;
752
+ // tslint:disable-next-line:no-any
753
+ ( compilation as any ) . _ngToolsWebpackPluginInstance = this ;
740
754
741
755
// Update the resource loader with the new webpack compilation.
742
756
this . _resourceLoader . update ( compilation ) ;
743
757
744
- this . _donePromise = Promise . resolve ( )
758
+ return this . _donePromise = Promise . resolve ( )
745
759
. then ( ( ) => this . _update ( ) )
746
760
. then ( ( ) => {
747
761
this . pushCompilationErrors ( compilation ) ;
748
762
timeEnd ( 'AngularCompilerPlugin._make' ) ;
749
- cb ( ) ;
750
- } , ( err : any ) => {
763
+ } , err => {
751
764
compilation . errors . push ( err ) ;
752
765
this . pushCompilationErrors ( compilation ) ;
753
766
timeEnd ( 'AngularCompilerPlugin._make' ) ;
754
- cb ( ) ;
755
767
} ) ;
756
768
}
757
769
758
- private pushCompilationErrors ( compilation : any ) {
770
+ private pushCompilationErrors ( compilation : compilation . Compilation ) {
759
771
compilation . errors . push ( ...this . _errors ) ;
760
772
compilation . warnings . push ( ...this . _warnings ) ;
761
773
this . _errors = [ ] ;
0 commit comments