Skip to content

Commit 5cedd34

Browse files
committed
refactor(@angular-devkit/build-angular): integrate ivy-only compiler plugin
1 parent a169a85 commit 5cedd34

File tree

1 file changed

+113
-15
lines changed
  • packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs

1 file changed

+113
-15
lines changed

packages/angular_devkit/build_angular/src/angular-cli-files/models/webpack-configs/typescript.ts

+113-15
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,69 @@ import {
1313
AngularCompilerPlugin,
1414
AngularCompilerPluginOptions,
1515
NgToolsLoader,
16-
PLATFORM
16+
PLATFORM,
17+
ivy,
1718
} from '@ngtools/webpack';
1819
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+
}
1979

2080
function _pluginOptionsOverrides(
2181
buildOptions: BuildOptions,
@@ -103,40 +163,78 @@ function _createAotPlugin(
103163

104164
export function getNonAotConfig(wco: WebpackConfigOptions) {
105165
const { tsConfigPath } = wco;
166+
const useIvyOnlyPlugin = canUseIvyPlugin(wco);
106167

107168
return {
108-
module: { rules: [{ test: /\.tsx?$/, loader: NgToolsLoader }] },
109-
plugins: [_createAotPlugin(wco, { tsConfigPath, skipCodeGeneration: true })]
169+
module: {
170+
rules: [
171+
{
172+
test: useIvyOnlyPlugin ? /\.[jt]sx?$/ : /\.tsx?$/,
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

113187
export 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 = /(?:\.ngfactory\.js|\.ngstyle\.js|\.tsx?)$/;
125-
const optimize = wco.buildOptions.optimization.scripts;
126-
127200
return {
128-
module: { rules: [{ test, use: loaders }] },
201+
module: {
202+
rules: [
203+
{
204+
test: useIvyOnlyPlugin ? /\.tsx?$/ : /(?:\.ngfactory\.js|\.ngstyle\.js|\.tsx?)$/,
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: /\.jsx?$/,
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

139233
export 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

Comments
 (0)