1
- import 'reflect-metadata' ;
2
1
import { NgModule } from '@angular/core' ;
3
2
import * as ts from 'typescript' ;
4
3
import * as ngCompiler from '@angular/compiler-cli' ;
5
4
import { tsc } from '@angular/tsc-wrapped/src/tsc' ;
6
5
import * as path from 'path' ;
7
6
8
-
9
- import { createCodeGenerator } from './codegen ' ;
10
- import { createResolveDependenciesFromContextMap } from './utils ' ;
7
+ import { WebpackResourceLoader } from './resource_loader' ;
8
+ import { createResolveDependenciesFromContextMap } from './utils ' ;
9
+ import { AngularCompilerOptions } from '@angular/tsc-wrapped ' ;
11
10
12
11
13
12
/**
@@ -20,154 +19,153 @@ export interface AngularWebpackPluginOptions {
20
19
tsconfigPath ?: string ;
21
20
compilerMode ?: NgcCompilerMode ;
22
21
providers ?: any [ ] ;
23
- entryModule : string ;
22
+ entryModule ?: string ;
23
+ project : string ;
24
+ baseDir : string ;
24
25
}
25
26
26
27
27
28
export class NgcWebpackPlugin {
28
29
projectPath : string ;
29
30
rootModule : string ;
30
31
rootModuleName : string ;
31
- codeGeneratorFactory : any ;
32
32
reflector : ngCompiler . StaticReflector ;
33
33
reflectorHost : ngCompiler . ReflectorHost ;
34
34
program : ts . Program ;
35
35
compilerHost : ts . CompilerHost ;
36
36
compilerOptions : ts . CompilerOptions ;
37
- angularCompilerOptions : any ;
37
+ angularCompilerOptions : AngularCompilerOptions ;
38
38
files : any [ ] ;
39
- contextRegex = / .* / ;
40
39
lazyRoutes : any ;
40
+ loader : any ;
41
+
42
+
43
+ nmf : any = null ;
44
+ cmf : any = null ;
45
+ compiler : any = null ;
46
+ compilation : any = null ;
41
47
42
- constructor ( public options : any = { } ) {
48
+ constructor ( public options : AngularWebpackPluginOptions ) {
43
49
const tsConfig = tsc . readConfiguration ( options . project , options . baseDir ) ;
44
50
this . compilerOptions = tsConfig . parsed . options ;
45
51
this . files = tsConfig . parsed . fileNames ;
46
52
this . angularCompilerOptions = tsConfig . ngOptions ;
47
53
48
54
if ( ! this . angularCompilerOptions ) {
49
- // TODO:robwormald more validation here
55
+ // TODO: more validation here
50
56
throw new Error ( `"angularCompilerOptions" is not set in your tsconfig file!` ) ;
51
57
}
52
58
this . angularCompilerOptions . basePath = options . baseDir || process . cwd ( ) ;
53
59
54
- const [ rootModule , rootNgModule ] = this . angularCompilerOptions . entryModule . split ( '#' ) ;
60
+ const [ rootModule , rootNgModule ] = ( this . angularCompilerOptions as any ) . entryModule . split ( '#' ) ;
55
61
this . projectPath = options . project ;
56
62
this . rootModule = rootModule ;
57
63
this . rootModuleName = rootNgModule ;
58
64
59
65
this . compilerHost = ts . createCompilerHost ( this . compilerOptions , true ) ;
60
66
this . program = ts . createProgram ( this . files , this . compilerOptions , this . compilerHost ) ;
61
67
62
- // TODO: pick this up from ngOptions
63
- const i18nOptions = {
64
- i18nFile : undefined ,
65
- i18nFormat : undefined ,
66
- locale : undefined ,
67
- basePath : options . baseDir
68
- } ;
69
-
70
68
this . reflectorHost = new ngCompiler . ReflectorHost (
71
69
this . program , this . compilerHost , tsConfig . ngOptions ) ;
72
70
this . reflector = new ngCompiler . StaticReflector ( this . reflectorHost ) ;
73
- this . codeGeneratorFactory = createCodeGenerator ( {
74
- ngcOptions : tsConfig . ngOptions ,
75
- i18nOptions,
76
- compilerHost : this . compilerHost ,
77
- resourceLoader : undefined // TODO: handle styles/templatess here.
78
- } ) ;
79
71
}
80
72
81
73
// registration hook for webpack plugin
82
74
apply ( compiler ) {
83
- compiler . plugin ( 'context-module-factory' , ( cmf ) => this . _resolveImports ( cmf ) ) ;
84
- compiler . plugin ( 'make' , ( compiler , cb ) => this . _make ( compiler , cb ) ) ;
85
- }
86
-
87
- private _resolveImports ( contextModuleFactory ) {
88
- contextModuleFactory . plugin ( 'before-resolve' , ( request , callback ) => {
89
- return this . _beforeResolveImports ( request , callback ) ;
90
- } ) ;
91
- contextModuleFactory . plugin ( 'after-resolve' , ( request , callback ) => {
92
- return this . _afterResolveImports ( request , callback ) ;
93
- } ) ;
94
- return contextModuleFactory ;
95
- }
96
-
97
- private _beforeResolveImports ( result , callback ) {
98
- if ( ! result ) {
99
- return callback ( ) ;
100
- }
101
- if ( this . contextRegex . test ( result . request ) ) {
102
- result . request = path . resolve ( process . cwd ( ) , 'app/ngfactory' ) ;
103
- result . recursive = true ;
104
- result . dependencies . forEach ( d => d . critical = false ) ;
105
- }
106
-
107
- return callback ( null , result ) ;
108
- }
109
-
110
- private _afterResolveImports ( result , callback ) {
111
- if ( ! result ) {
112
- return callback ( ) ;
113
- }
114
-
115
- if ( this . contextRegex . test ( result . resource ) ) {
116
- result . resource = path . resolve ( process . cwd ( ) , this . angularCompilerOptions . genDir + '/app' ) ;
117
- result . recursive = true ;
118
- result . dependencies . forEach ( d => d . critical = false ) ;
119
- result . resolveDependencies = createResolveDependenciesFromContextMap ( ( fs , cb ) => {
120
- return cb ( null , this . lazyRoutes ) ;
75
+ this . compiler = compiler ;
76
+ compiler . plugin ( 'normal-module-factory' , ( nmf ) => this . nmf = nmf ) ;
77
+ compiler . plugin ( 'context-module-factory' , ( cmf ) => {
78
+ this . cmf = cmf ;
79
+ cmf . plugin ( 'before-resolve' , ( request , callback ) => {
80
+ if ( ! request ) {
81
+ console . log ( 11 ) ;
82
+ return callback ( ) ;
83
+ }
84
+
85
+ request . request = path . resolve ( process . cwd ( ) , 'app/ngfactory' ) ;
86
+ request . recursive = true ;
87
+ request . dependencies . forEach ( d => d . critical = false ) ;
88
+ console . log ( 1 ) ;
89
+ return callback ( null , request ) ;
121
90
} ) ;
122
- }
123
- return callback ( null , result ) ;
91
+ cmf . plugin ( 'after-resolve' , ( result , callback ) => {
92
+ if ( ! result ) {
93
+ console . log ( 10 ) ;
94
+ return callback ( ) ;
95
+ }
96
+
97
+ result . resource = path . resolve ( process . cwd ( ) , this . angularCompilerOptions . genDir + '/app' ) ;
98
+ result . recursive = true ;
99
+ result . dependencies . forEach ( d => d . critical = false ) ;
100
+ result . resolveDependencies = createResolveDependenciesFromContextMap ( ( fs , cb ) => {
101
+ console . log ( 4 ) ;
102
+ return cb ( null , this . lazyRoutes ) ;
103
+ } ) ;
104
+
105
+ return callback ( null , result ) ;
106
+ } ) ;
107
+ } ) ;
108
+ compiler . plugin ( 'make' , ( compiler , cb ) => this . _make ( compiler , cb ) ) ;
124
109
}
125
110
126
111
private _make ( compilation , cb ) {
127
112
const rootModulePath = path . normalize ( this . rootModule + '.ts' ) ;
128
113
const rootModuleName = this . rootModuleName ;
114
+ this . compilation = compilation ;
115
+ this . loader = new WebpackResourceLoader ( compilation ) ;
129
116
130
- // process the lazy routes
131
- const lazyModules = this . _processNgModule ( rootModulePath , rootModuleName , rootModulePath )
132
- . map ( moduleKey => moduleKey . split ( '#' ) [ 0 ] ) ;
133
117
const program = ts . createProgram ( this . files , this . compilerOptions , this . compilerHost ) ;
134
118
135
- this . codeGeneratorFactory ( program )
136
- . reduce ( ( files , generatedFile ) => files . concat ( generatedFile ) , [ ] )
137
- . do ( files => console . log ( `ngc: generated ${ files . length } files` ) )
138
- . map ( ( ) => {
139
- return lazyModules . reduce ( ( lazyRoutes , lazyModule ) => {
140
- const lazyPath = `${ lazyModule } .ngfactory` ;
141
- lazyRoutes [ lazyPath ] = path . join (
142
- path . resolve ( process . cwd ( ) , this . angularCompilerOptions . genDir + '/app' ) ,
143
- lazyModule + '.ngfactory.ts'
119
+ const i18nOptions = {
120
+ i18nFile : undefined ,
121
+ i18nFormat : undefined ,
122
+ locale : undefined ,
123
+ basePath : this . options . baseDir
124
+ } ;
125
+
126
+ // Create the Code Generator.
127
+ const codeGenerator = ngCompiler . CodeGenerator . create (
128
+ this . angularCompilerOptions ,
129
+ i18nOptions ,
130
+ program ,
131
+ this . compilerHost ,
132
+ new ngCompiler . NodeReflectorHostContext ( this . compilerHost ) ,
133
+ this . loader
134
+ ) ;
135
+
136
+ codeGenerator . codegen ( )
137
+ . then ( ( ) => {
138
+ // process the lazy routes
139
+ const lazyModules = this . _processNgModule ( rootModulePath , rootModuleName , rootModulePath )
140
+ . map ( moduleKey => moduleKey . split ( '#' ) [ 0 ] ) ;
141
+ this . lazyRoutes = lazyModules . reduce ( ( lazyRoutes , lazyModule ) => {
142
+ lazyRoutes [ `${ lazyModule } .ngfactory` ] = path . join (
143
+ path . resolve ( process . cwd ( ) , this . angularCompilerOptions . genDir ) ,
144
+ 'app' , lazyModule + '.ngfactory.ts'
144
145
) ;
145
146
return lazyRoutes ;
146
147
} , { } ) ;
148
+ console . log ( 2 , this . lazyRoutes ) ;
147
149
} )
148
- . do ( lazyRouteConfig => this . lazyRoutes = lazyRouteConfig )
149
- . forEach ( v => console . log ( 'codegen complete' ) )
150
- . then (
151
- _ => cb ( ) ,
152
- err => cb ( err )
153
- ) ;
150
+ . then ( ( ) => {
151
+ console . log ( 3 ) ;
152
+ cb ( )
153
+ } , ( err ) => cb ( err ) ) ;
154
154
}
155
155
156
156
private _processNgModule ( mod : string , ngModuleName : string , containingFile : string ) : string [ ] {
157
157
const staticSymbol = this . reflectorHost . findDeclaration ( mod , ngModuleName , containingFile ) ;
158
158
const entryNgModuleMetadata = this . getNgModuleMetadata ( staticSymbol ) ;
159
159
const loadChildren = this . extractLoadChildren ( entryNgModuleMetadata ) ;
160
160
161
- const moduleChildren = loadChildren . reduce ( ( res , lc ) => {
162
- const [ childMoudle , childNgModule ] = lc . split ( '#' ) ;
161
+ return loadChildren . reduce ( ( res , lc ) => {
162
+ const [ childModule , childNgModule ] = lc . split ( '#' ) ;
163
163
164
164
// TODO calculate a different containingFile for relative paths
165
165
166
- const children = this . _processNgModule ( childMoudle , childNgModule , containingFile ) ;
166
+ const children = this . _processNgModule ( childModule , childNgModule , containingFile ) ;
167
167
return res . concat ( children ) ;
168
168
} , loadChildren ) ;
169
-
170
- return moduleChildren ;
171
169
}
172
170
173
171
private getNgModuleMetadata ( staticSymbol : ngCompiler . StaticSymbol ) {
@@ -209,32 +207,14 @@ export class NgcWebpackPlugin {
209
207
}
210
208
return routes . reduce ( ( m , r ) => {
211
209
if ( r . loadChildren ) {
212
- return m . concat ( [ r . loadChildren ] ) ;
213
-
210
+ return m . concat ( r . loadChildren ) ;
214
211
} else if ( Array . isArray ( r ) ) {
215
212
return m . concat ( this . collectLoadChildren ( r ) ) ;
216
-
217
213
} else if ( r . children ) {
218
214
return m . concat ( this . collectLoadChildren ( r . children ) ) ;
219
-
220
215
} else {
221
216
return m ;
222
217
}
223
218
} , [ ] ) ;
224
219
}
225
220
}
226
-
227
- class ParseConfigHost implements ts . ParseConfigHost {
228
- useCaseSensitiveFileNames : boolean = true ;
229
-
230
- readDirectory ( rootDir : string , extensions : string [ ] , excludes : string [ ] , includes : string [ ] ) {
231
- return ts . sys . readDirectory ( rootDir , extensions , excludes , includes ) ;
232
- }
233
- /**
234
- * Gets a value indicating whether the specified path exists and is a file.
235
- * @param path The path to test.
236
- */
237
- fileExists ( path : string ) : boolean {
238
- return ts . sys . fileExists ( path ) ;
239
- }
240
- }
0 commit comments