Skip to content

Commit e253fff

Browse files
alan-agius4mgechev
authored andcommitted
refactor(@angular-devkit/build-angular): move addition of HMR plugins and loaders to webpack configs
1 parent 7253802 commit e253fff

File tree

8 files changed

+42
-40
lines changed

8 files changed

+42
-40
lines changed

packages/angular_devkit/build_angular/src/browser/index.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import * as webpack from 'webpack';
1919
import { ExecutionTransformer } from '../transforms';
2020
import {
2121
BuildBrowserFeatures,
22+
NormalizedBrowserBuilderSchema,
2223
deleteOutputDir,
2324
normalizeAssetPatterns,
2425
normalizeOptimization,
@@ -105,7 +106,7 @@ export async function buildBrowserWebpackConfigFromContext(
105106
options: BrowserBuilderSchema,
106107
context: BuilderContext,
107108
host: virtualFs.Host<fs.Stats> = new NodeJsSyncHost(),
108-
differentialLoadingMode = false,
109+
extraBuildOptions: Partial<NormalizedBrowserBuilderSchema> = {},
109110
): Promise<ConfigFromContextReturn> {
110111
const webpackPartialGenerator = (wco: BrowserWebpackConfigOptions) => [
111112
getCommonConfig(wco),
@@ -122,7 +123,7 @@ export async function buildBrowserWebpackConfigFromContext(
122123
context,
123124
webpackPartialGenerator,
124125
host,
125-
differentialLoadingMode,
126+
extraBuildOptions,
126127
);
127128
}
128129

@@ -192,7 +193,7 @@ async function initialize(
192193
projectRoot,
193194
projectSourceRoot,
194195
i18n,
195-
} = await buildBrowserWebpackConfigFromContext(adjustedOptions, context, host, differentialLoadingMode);
196+
} = await buildBrowserWebpackConfigFromContext(adjustedOptions, context, host, { differentialLoadingMode });
196197

197198
// Validate asset option values if processed directly
198199
if (options.assets?.length && !adjustedOptions.assets?.length) {

packages/angular_devkit/build_angular/src/dev-server/index.ts

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ import { readTsconfig } from '../utils/read-tsconfig';
3737
import { assertCompatibleAngularVersion } from '../utils/version';
3838
import { getIndexInputFile, getIndexOutputFile } from '../utils/webpack-browser-config';
3939
import { addError, addWarning } from '../utils/webpack-diagnostics';
40-
import { HmrLoader } from '../webpack/plugins/hmr/hmr-loader';
4140
import { IndexHtmlWebpackPlugin } from '../webpack/plugins/index-html-webpack-plugin';
4241
import { createWebpackLoggingCallback } from '../webpack/utils/stats';
4342
import { Schema } from './schema';
@@ -120,6 +119,7 @@ export function serveWebpackBrowser(
120119
browserOptions,
121120
context,
122121
host,
122+
{ hmr: options.hmr },
123123
);
124124
let webpackConfig = config;
125125

@@ -571,23 +571,8 @@ function _addLiveReload(
571571
entryPoints.push(
572572
'webpack/hot/dev-server',
573573
);
574-
575-
webpackConfig.plugins.push(new webpack.HotModuleReplacementPlugin());
576-
577-
const hmrLoader: webpack.RuleSetRule = {
578-
loader: HmrLoader,
579-
include: [browserOptions.main].map(p => path.resolve(root, p)),
580-
};
581-
582-
if (typeof webpackConfig.module !== 'object') {
583-
webpackConfig.module = {
584-
rules: [hmrLoader],
585-
};
586-
} else {
587-
webpackConfig.module.rules.unshift(hmrLoader);
588-
}
589-
590574
}
575+
591576
if (typeof webpackConfig.entry !== 'object' || Array.isArray(webpackConfig.entry)) {
592577
webpackConfig.entry = {};
593578
}

packages/angular_devkit/build_angular/src/utils/build-options.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export interface BuildOptions {
6060
webWorkerTsConfig?: string;
6161
statsJson: boolean;
6262
forkTypeChecker: boolean;
63+
hmr?: boolean;
6364

6465
main: string;
6566
polyfills?: string;
@@ -77,6 +78,8 @@ export interface BuildOptions {
7778

7879
experimentalRollupPass?: boolean;
7980
allowedCommonJsDependencies?: string[];
81+
82+
differentialLoadingMode?: boolean;
8083
}
8184

8285
export interface WebpackTestOptions extends BuildOptions {
@@ -93,5 +96,4 @@ export interface WebpackConfigOptions<T = BuildOptions> {
9396
tsConfig: ParsedConfiguration;
9497
tsConfigPath: string;
9598
supportES2015: boolean;
96-
differentialLoadingMode?: boolean;
9799
}

packages/angular_devkit/build_angular/src/utils/webpack-browser-config.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export async function generateWebpackConfig(
3939
options: NormalizedBrowserBuilderSchema,
4040
webpackPartialGenerator: (wco: BrowserWebpackConfigOptions) => webpack.Configuration[],
4141
logger: logging.LoggerApi,
42-
differentialLoadingMode: boolean,
42+
extraBuildOptions: Partial<NormalizedBrowserBuilderSchema>,
4343
): Promise<webpack.Configuration> {
4444
// Ensure Build Optimizer is only used with AOT.
4545
if (options.buildOptimizer && !options.aot) {
@@ -67,7 +67,7 @@ export async function generateWebpackConfig(
6767

6868
const supportES2015 = scriptTarget !== ts.ScriptTarget.JSON && scriptTarget > ts.ScriptTarget.ES5;
6969

70-
const buildOptions: NormalizedBrowserBuilderSchema = { ...options };
70+
const buildOptions: NormalizedBrowserBuilderSchema = { ...options, ...extraBuildOptions };
7171
const wco: BrowserWebpackConfigOptions = {
7272
root: workspaceRoot,
7373
logger: logger.createChild('webpackConfigOptions'),
@@ -77,7 +77,6 @@ export async function generateWebpackConfig(
7777
tsConfig,
7878
tsConfigPath,
7979
supportES2015,
80-
differentialLoadingMode,
8180
};
8281

8382
wco.buildOptions.progress = defaultProgress(wco.buildOptions.progress);
@@ -104,7 +103,7 @@ export async function generateWebpackConfig(
104103
if (profilingEnabled) {
105104
const esVersionInFileName = getEsVersionForFileName(
106105
tsConfig.options.target,
107-
wco.differentialLoadingMode,
106+
buildOptions.differentialLoadingMode,
108107
);
109108

110109
const SpeedMeasurePlugin = await import('speed-measure-webpack-plugin');
@@ -127,15 +126,15 @@ export async function generateI18nBrowserWebpackConfigFromContext(
127126
context: BuilderContext,
128127
webpackPartialGenerator: (wco: BrowserWebpackConfigOptions) => webpack.Configuration[],
129128
host: virtualFs.Host<fs.Stats> = new NodeJsSyncHost(),
130-
differentialLoadingMode = false,
129+
extraBuildOptions: Partial<NormalizedBrowserBuilderSchema> = {},
131130
): Promise<{ config: webpack.Configuration; projectRoot: string; projectSourceRoot?: string, i18n: I18nOptions }> {
132131
const { buildOptions, i18n } = await configureI18nBuild(context, options);
133132
const result = await generateBrowserWebpackConfigFromContext(
134133
buildOptions,
135134
context,
136135
webpackPartialGenerator,
137136
host,
138-
differentialLoadingMode,
137+
extraBuildOptions,
139138
);
140139
const config = result.config;
141140

@@ -197,7 +196,7 @@ export async function generateBrowserWebpackConfigFromContext(
197196
context: BuilderContext,
198197
webpackPartialGenerator: (wco: BrowserWebpackConfigOptions) => webpack.Configuration[],
199198
host: virtualFs.Host<fs.Stats> = new NodeJsSyncHost(),
200-
differentialLoadingMode = false,
199+
extraBuildOptions: Partial<NormalizedBrowserBuilderSchema> = {},
201200
): Promise<{ config: webpack.Configuration; projectRoot: string; projectSourceRoot?: string }> {
202201
const projectName = context.target && context.target.project;
203202
if (!projectName) {
@@ -227,7 +226,7 @@ export async function generateBrowserWebpackConfigFromContext(
227226
normalizedOptions,
228227
webpackPartialGenerator,
229228
context.logger,
230-
differentialLoadingMode,
229+
extraBuildOptions,
231230
);
232231

233232
return {

packages/angular_devkit/build_angular/src/webpack/configs/browser.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8+
import { resolve } from 'path';
89
import * as webpack from 'webpack';
910
import { WebpackConfigOptions } from '../../utils/build-options';
1011
import { withWebpackFourOrFive } from '../../utils/webpack-version';
1112
import { CommonJsUsageWarnPlugin } from '../plugins';
13+
import { HmrLoader } from '../plugins/hmr/hmr-loader';
1214
import { getSourceMapDevTool } from '../utils/helpers';
1315

1416
export function getBrowserConfig(wco: WebpackConfigOptions): webpack.Configuration {
@@ -20,6 +22,7 @@ export function getBrowserConfig(wco: WebpackConfigOptions): webpack.Configurati
2022
vendorChunk,
2123
commonChunk,
2224
allowedCommonJsDependencies,
25+
hmr,
2326
} = buildOptions;
2427

2528
const extraPlugins = [];
@@ -54,7 +57,7 @@ export function getBrowserConfig(wco: WebpackConfigOptions): webpack.Configurati
5457
extraPlugins.push(getSourceMapDevTool(
5558
scriptsSourceMap,
5659
stylesSourceMap,
57-
wco.differentialLoadingMode ? true : hiddenSourceMap,
60+
buildOptions.differentialLoadingMode ? true : hiddenSourceMap,
5861
false,
5962
vendorSourceMap,
6063
));
@@ -67,11 +70,24 @@ export function getBrowserConfig(wco: WebpackConfigOptions): webpack.Configurati
6770
crossOriginLoading = crossOrigin;
6871
}
6972

73+
const extraRules: webpack.RuleSetRule[] = [];
74+
if (hmr) {
75+
extraRules.push({
76+
loader: HmrLoader,
77+
include: [buildOptions.main].map(p => resolve(wco.root, p)),
78+
});
79+
80+
extraPlugins.push(new webpack.HotModuleReplacementPlugin());
81+
}
82+
7083
return {
7184
devtool: false,
7285
resolve: {
7386
mainFields: ['es2015', 'browser', 'module', 'main'],
7487
},
88+
module: {
89+
rules: extraRules,
90+
},
7591
...withWebpackFourOrFive({}, { target: ['web', 'es5'] }),
7692
output: {
7793
crossOriginLoading,

packages/angular_devkit/build_angular/src/webpack/configs/common.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export function getCommonConfig(wco: WebpackConfigOptions): Configuration {
7070

7171
const targetInFileName = getEsVersionForFileName(
7272
tsConfig.options.target,
73-
wco.differentialLoadingMode,
73+
buildOptions.differentialLoadingMode,
7474
);
7575

7676
if (buildOptions.main) {
@@ -121,7 +121,7 @@ export function getCommonConfig(wco: WebpackConfigOptions): Configuration {
121121
}
122122
}
123123

124-
const differentialLoadingMode = !!wco.differentialLoadingMode;
124+
const differentialLoadingMode = buildOptions.differentialLoadingMode;
125125
if (wco.buildOptions.platform !== 'server') {
126126
if (differentialLoadingMode || tsConfig.options.target === ScriptTarget.ES5) {
127127
const buildBrowserFeatures = new BuildBrowserFeatures(

packages/angular_devkit/build_angular/src/webpack/configs/styles.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,12 +258,16 @@ export function getStylesConfig(wco: WebpackConfigOptions) {
258258
}
259259

260260
if (buildOptions.extractCss) {
261+
// extract global css from js files into own css file.
261262
extraPlugins.push(
262-
// extract global css from js files into own css file
263263
new MiniCssExtractPlugin({ filename: `[name]${hashFormat.extract}.css` }),
264-
// suppress empty .js files in css only entry points
265-
new SuppressExtractedTextChunksWebpackPlugin(),
266264
);
265+
266+
if (!buildOptions.hmr) {
267+
// don't remove `.js` files for `.css` when we are using HMR these contain HMR accept codes.
268+
// suppress empty .js files in css only entry points.
269+
extraPlugins.push(new SuppressExtractedTextChunksWebpackPlugin());
270+
}
267271
}
268272

269273
return {

packages/angular_devkit/build_angular/src/webpack/plugins/suppress-entry-chunks-webpack-plugin.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,6 @@ export class SuppressExtractedTextChunksWebpackPlugin {
1414
apply(compiler: import('webpack').Compiler): void {
1515
compiler.hooks.compilation.tap('SuppressExtractedTextChunks', (compilation) => {
1616
compilation.hooks.chunkAsset.tap('SuppressExtractedTextChunks', (chunk, filename) => {
17-
if (compiler.options?.devServer?.hot) {
18-
// don't remove `.js` files for `.css` when we are using HMR these contain HMR accept codes.
19-
return;
20-
}
21-
2217
// Remove only JavaScript assets
2318
if (!filename.endsWith('.js')) {
2419
return;

0 commit comments

Comments
 (0)