@@ -13,9 +13,73 @@ 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 '../../utils/build-options' ;
20
+ import { CompilerOptions } from '@angular/compiler-cli' ;
21
+ import { RuleSetLoader } from 'webpack' ;
22
+
23
+ function canUseIvyPlugin ( wco : WebpackConfigOptions ) : boolean {
24
+ // Can only be used with Ivy
25
+ if ( ! wco . tsConfig . options . enableIvy ) {
26
+ return false ;
27
+ }
28
+
29
+ // Allow fallback to legacy build system via environment variable ('NG_BUILD_IVY_LEGACY=1')
30
+ const flag = process . env [ 'NG_BUILD_IVY_LEGACY' ] ;
31
+ if ( flag !== undefined && flag !== '0' && flag . toLowerCase ( ) !== 'false' ) {
32
+ wco . logger . warn (
33
+ '"NG_BUILD_IVY_LEGACY" environment variable detected. Using legacy Ivy build system.' ,
34
+ ) ;
35
+
36
+ return false ;
37
+ }
38
+
39
+ // Lazy modules option uses the deprecated string format for lazy routes
40
+ if ( wco . buildOptions . lazyModules && wco . buildOptions . lazyModules . length > 0 ) {
41
+ return false ;
42
+ }
43
+
44
+ // This pass relies on internals of the original plugin
45
+ if ( wco . buildOptions . experimentalRollupPass ) {
46
+ return false ;
47
+ }
48
+
49
+ return true ;
50
+ }
51
+
52
+ function createIvyPlugin (
53
+ wco : WebpackConfigOptions ,
54
+ aot : boolean ,
55
+ tsconfig : string ,
56
+ ) : ivy . AngularWebpackPlugin {
57
+ const { buildOptions } = wco ;
58
+ const optimize = buildOptions . optimization . scripts ;
59
+
60
+ const compilerOptions : CompilerOptions = {
61
+ skipTemplateCodegen : ! aot ,
62
+ sourceMap : buildOptions . sourceMap . scripts ,
63
+ } ;
64
+
65
+ if ( buildOptions . preserveSymlinks !== undefined ) {
66
+ compilerOptions . preserveSymlinks = buildOptions . preserveSymlinks ;
67
+ }
68
+
69
+ const fileReplacements : Record < string , string > = { } ;
70
+ if ( buildOptions . fileReplacements ) {
71
+ for ( const replacement of buildOptions . fileReplacements ) {
72
+ fileReplacements [ replacement . replace ] = replacement . with ;
73
+ }
74
+ }
75
+
76
+ return new ivy . AngularWebpackPlugin ( {
77
+ tsconfig,
78
+ compilerOptions,
79
+ fileReplacements,
80
+ emitNgModuleScope : ! optimize ,
81
+ } ) ;
82
+ }
19
83
20
84
function _pluginOptionsOverrides (
21
85
buildOptions : BuildOptions ,
@@ -112,31 +176,55 @@ export function getNonAotConfig(wco: WebpackConfigOptions) {
112
176
113
177
export function getAotConfig ( wco : WebpackConfigOptions , i18nExtract = false ) {
114
178
const { tsConfigPath, buildOptions } = wco ;
179
+ const optimize = buildOptions . optimization . scripts ;
180
+ const useIvyOnlyPlugin = canUseIvyPlugin ( wco ) && ! i18nExtract ;
115
181
116
- const loaders : any [ ] = [ NgToolsLoader ] ;
182
+ let buildOptimizerRules : RuleSetLoader [ ] = [ ] ;
117
183
if ( buildOptions . buildOptimizer ) {
118
- loaders . unshift ( {
184
+ buildOptimizerRules = [ {
119
185
loader : buildOptimizerLoaderPath ,
120
186
options : { sourceMap : buildOptions . sourceMap . scripts }
121
- } ) ;
187
+ } ] ;
122
188
}
123
189
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
190
return {
128
- module : { rules : [ { test, use : loaders } ] } ,
191
+ module : {
192
+ rules : [
193
+ {
194
+ 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 ? ) $ / ,
195
+ use : [
196
+ ...buildOptimizerRules ,
197
+ useIvyOnlyPlugin ? ivy . AngularWebpackLoaderPath : NgToolsLoader ,
198
+ ] ,
199
+ } ,
200
+ // "allowJs" support with ivy plugin - ensures build optimizer is not run twice
201
+ ...( useIvyOnlyPlugin
202
+ ? [
203
+ {
204
+ test : / \. j s x ? $ / ,
205
+ use : [ ivy . AngularWebpackLoaderPath ] ,
206
+ } ,
207
+ ]
208
+ : [ ] ) ,
209
+ ] ,
210
+ } ,
129
211
plugins : [
130
- _createAotPlugin (
131
- wco ,
132
- { tsConfigPath, emitClassMetadata : ! optimize , emitNgModuleScope : ! optimize } ,
133
- i18nExtract ,
134
- ) ,
212
+ useIvyOnlyPlugin
213
+ ? createIvyPlugin ( wco , true , tsConfigPath )
214
+ : _createAotPlugin (
215
+ wco ,
216
+ { tsConfigPath, emitClassMetadata : ! optimize , emitNgModuleScope : ! optimize } ,
217
+ i18nExtract ,
218
+ ) ,
135
219
] ,
136
220
} ;
137
221
}
138
222
139
223
export function getTypescriptWorkerPlugin ( wco : WebpackConfigOptions , workerTsConfigPath : string ) {
224
+ if ( wco . buildOptions . aot && canUseIvyPlugin ( wco ) ) {
225
+ return createIvyPlugin ( wco , false , workerTsConfigPath ) ;
226
+ }
227
+
140
228
const { buildOptions } = wco ;
141
229
142
230
let pluginOptions : AngularCompilerPluginOptions = {
0 commit comments