@@ -13,9 +13,69 @@ import {
13
13
AngularCompilerPlugin ,
14
14
AngularCompilerPluginOptions ,
15
15
NgToolsLoader ,
16
- PLATFORM
16
+ PLATFORM ,
17
+ ivy ,
17
18
} from '@ngtools/webpack' ;
18
19
import { WebpackConfigOptions , BuildOptions } from '../build-options' ;
20
+ import { CompilerOptions } from '@angular/compiler-cli' ;
21
+ import { RuleSetLoader } from 'webpack' ;
22
+
23
+ function canUseIvyPlugin ( wco : WebpackConfigOptions ) : boolean {
24
+ // const flag = process.env['NG_BUILD_IVY_PLUGIN'];
25
+ // if (!flag || flag === '0' || flag.toLowerCase() === 'false') {
26
+ // return false;
27
+ // }
28
+
29
+ // Can only be used with Ivy
30
+ if ( ! wco . tsConfig . options . enableIvy ) {
31
+ return false ;
32
+ }
33
+
34
+ // Lazy modules option uses the deprecated string format for lazy routes which is not supported
35
+ if ( wco . buildOptions . lazyModules && wco . buildOptions . lazyModules . length > 0 ) {
36
+ return false ;
37
+ }
38
+
39
+ // This pass relies on internals of the original plugin
40
+ if ( wco . buildOptions . experimentalRollupPass ) {
41
+ return false ;
42
+ }
43
+
44
+ return true ;
45
+ }
46
+
47
+ function createIvyPlugin (
48
+ wco : WebpackConfigOptions ,
49
+ aot : boolean ,
50
+ tsconfig : string ,
51
+ ) : ivy . AngularWebpackPlugin {
52
+ const { buildOptions } = wco ;
53
+ const optimize = buildOptions . optimization . scripts ;
54
+
55
+ const compilerOptions : CompilerOptions = {
56
+ skipTemplateCodegen : ! aot ,
57
+ sourceMap : buildOptions . sourceMap . scripts ,
58
+ } ;
59
+
60
+ if ( buildOptions . preserveSymlinks !== undefined ) {
61
+ compilerOptions . preserveSymlinks = buildOptions . preserveSymlinks ;
62
+ }
63
+
64
+ const fileReplacements : Record < string , string > = { } ;
65
+ if ( buildOptions . fileReplacements ) {
66
+ for ( const replacement of buildOptions . fileReplacements ) {
67
+ fileReplacements [ replacement . replace ] = replacement . with ;
68
+ }
69
+ }
70
+
71
+ return new ivy . AngularWebpackPlugin ( {
72
+ tsconfig,
73
+ compilerOptions,
74
+ fileReplacements,
75
+ emitClassMetadata : ! optimize ,
76
+ emitNgModuleScope : ! optimize ,
77
+ } ) ;
78
+ }
19
79
20
80
function _pluginOptionsOverrides (
21
81
buildOptions : BuildOptions ,
@@ -103,40 +163,78 @@ function _createAotPlugin(
103
163
104
164
export function getNonAotConfig ( wco : WebpackConfigOptions ) {
105
165
const { tsConfigPath } = wco ;
166
+ const useIvyOnlyPlugin = canUseIvyPlugin ( wco ) ;
106
167
107
168
return {
108
- module : { rules : [ { test : / \. t s x ? $ / , loader : NgToolsLoader } ] } ,
109
- plugins : [ _createAotPlugin ( wco , { tsConfigPath, skipCodeGeneration : true } ) ]
169
+ module : {
170
+ rules : [
171
+ {
172
+ test : useIvyOnlyPlugin ? / \. [ j t ] s x ? $ / : / \. t s x ? $ / ,
173
+ loader : useIvyOnlyPlugin
174
+ ? ivy . AngularWebpackLoaderPath
175
+ : NgToolsLoader ,
176
+ } ,
177
+ ] ,
178
+ } ,
179
+ plugins : [
180
+ useIvyOnlyPlugin
181
+ ? createIvyPlugin ( wco , false , tsConfigPath )
182
+ : _createAotPlugin ( wco , { tsConfigPath, skipCodeGeneration : true } ) ,
183
+ ] ,
110
184
} ;
111
185
}
112
186
113
187
export function getAotConfig ( wco : WebpackConfigOptions , i18nExtract = false ) {
114
188
const { tsConfigPath, buildOptions } = wco ;
189
+ const optimize = buildOptions . optimization . scripts ;
190
+ const useIvyOnlyPlugin = canUseIvyPlugin ( wco ) && ! i18nExtract ;
115
191
116
- const loaders : any [ ] = [ NgToolsLoader ] ;
192
+ let buildOptimizerRules : RuleSetLoader [ ] = [ ] ;
117
193
if ( buildOptions . buildOptimizer ) {
118
- loaders . unshift ( {
194
+ buildOptimizerRules = [ {
119
195
loader : buildOptimizerLoaderPath ,
120
196
options : { sourceMap : buildOptions . sourceMap . scripts }
121
- } ) ;
197
+ } ] ;
122
198
}
123
199
124
- const test = / (?: \. n g f a c t o r y \. j s | \. n g s t y l e \. j s | \. t s x ? ) $ / ;
125
- const optimize = wco . buildOptions . optimization . scripts ;
126
-
127
200
return {
128
- module : { rules : [ { test, use : loaders } ] } ,
201
+ module : {
202
+ rules : [
203
+ {
204
+ test : useIvyOnlyPlugin ? / \. t s x ? $ / : / (?: \. n g f a c t o r y \. j s | \. n g s t y l e \. j s | \. t s x ? ) $ / ,
205
+ use : [
206
+ ...buildOptimizerRules ,
207
+ useIvyOnlyPlugin ? ivy . AngularWebpackLoaderPath : NgToolsLoader ,
208
+ ] ,
209
+ } ,
210
+ // "allowJs" support with ivy plugin - ensures build optimizer is not run twice
211
+ ...( useIvyOnlyPlugin
212
+ ? [
213
+ {
214
+ test : / \. j s x ? $ / ,
215
+ use : [ ivy . AngularWebpackLoaderPath ] ,
216
+ } ,
217
+ ]
218
+ : [ ] ) ,
219
+ ] ,
220
+ } ,
129
221
plugins : [
130
- _createAotPlugin (
131
- wco ,
132
- { tsConfigPath, emitClassMetadata : ! optimize , emitNgModuleScope : ! optimize } ,
133
- i18nExtract ,
134
- ) ,
222
+ useIvyOnlyPlugin
223
+ ? createIvyPlugin ( wco , true , tsConfigPath )
224
+ : _createAotPlugin (
225
+ wco ,
226
+ { tsConfigPath, emitClassMetadata : ! optimize , emitNgModuleScope : ! optimize } ,
227
+ i18nExtract ,
228
+ ) ,
135
229
] ,
136
230
} ;
137
231
}
138
232
139
233
export function getTypescriptWorkerPlugin ( wco : WebpackConfigOptions , workerTsConfigPath : string ) {
234
+ if ( canUseIvyPlugin ( wco ) ) {
235
+ return createIvyPlugin ( wco , false , workerTsConfigPath ) ;
236
+ }
237
+
140
238
const { buildOptions } = wco ;
141
239
142
240
let pluginOptions : AngularCompilerPluginOptions = {
0 commit comments