@@ -13,9 +13,69 @@ import {
1313 AngularCompilerPlugin ,
1414 AngularCompilerPluginOptions ,
1515 NgToolsLoader ,
16- PLATFORM
16+ PLATFORM ,
17+ ivy ,
1718} from '@ngtools/webpack' ;
1819import { 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+ }
1979
2080function _pluginOptionsOverrides (
2181 buildOptions : BuildOptions ,
@@ -103,40 +163,78 @@ function _createAotPlugin(
103163
104164export function getNonAotConfig ( wco : WebpackConfigOptions ) {
105165 const { tsConfigPath } = wco ;
166+ const useIvyOnlyPlugin = canUseIvyPlugin ( wco ) ;
106167
107168 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+ ] ,
110184 } ;
111185}
112186
113187export function getAotConfig ( wco : WebpackConfigOptions , i18nExtract = false ) {
114188 const { tsConfigPath, buildOptions } = wco ;
189+ const optimize = buildOptions . optimization . scripts ;
190+ const useIvyOnlyPlugin = canUseIvyPlugin ( wco ) && ! i18nExtract ;
115191
116- const loaders : any [ ] = [ NgToolsLoader ] ;
192+ let buildOptimizerRules : RuleSetLoader [ ] = [ ] ;
117193 if ( buildOptions . buildOptimizer ) {
118- loaders . unshift ( {
194+ buildOptimizerRules = [ {
119195 loader : buildOptimizerLoaderPath ,
120196 options : { sourceMap : buildOptions . sourceMap . scripts }
121- } ) ;
197+ } ] ;
122198 }
123199
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-
127200 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+ } ,
129221 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+ ) ,
135229 ] ,
136230 } ;
137231}
138232
139233export function getTypescriptWorkerPlugin ( wco : WebpackConfigOptions , workerTsConfigPath : string ) {
234+ if ( canUseIvyPlugin ( wco ) ) {
235+ return createIvyPlugin ( wco , false , workerTsConfigPath ) ;
236+ }
237+
140238 const { buildOptions } = wco ;
141239
142240 let pluginOptions : AngularCompilerPluginOptions = {
0 commit comments