Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(@angular-devkit/build-angular): enable HMR for extracted CSS #18514

Merged
merged 3 commits into from Aug 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/angular/cli/lib/config/schema.json
Expand Up @@ -797,17 +797,17 @@
"i18nFile": {
"type": "string",
"description": "Localization file to use for i18n.",
"x-deprecated": "Deprecated since 9.0"
"x-deprecated": "Deprecated since 9.0."
},
"i18nFormat": {
"type": "string",
"description": "Format of the localization file specified with --i18n-file.",
"x-deprecated": "Deprecated since 9.0"
"x-deprecated": "Deprecated since 9.0."
},
"i18nLocale": {
"type": "string",
"description": "Locale to use for i18n.",
"x-deprecated": "Deprecated since 9.0"
"x-deprecated": "Deprecated since 9.0."
},
"extractCss": {
"type": "boolean",
Expand Down
Expand Up @@ -47,6 +47,7 @@ export interface BuildOptions {
bundleDependencies?: boolean;
externalDependencies?: string[];
watch?: boolean;
hmr?: boolean;
outputHashing?: string;
poll?: number;
deleteOutputPath?: boolean;
Expand Down
Expand Up @@ -218,7 +218,14 @@ export function getStylesConfig(wco: WebpackConfigOptions) {
include: globalStylePaths,
test,
use: [
buildOptions.extractCss ? MiniCssExtractPlugin.loader : require.resolve('style-loader'),
buildOptions.extractCss
? {
loader: MiniCssExtractPlugin.loader,
options: {
hmr: buildOptions.hmr,
},
}
: require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
Expand Down
26 changes: 15 additions & 11 deletions packages/angular_devkit/build_angular/src/dev-server/index.ts
Expand Up @@ -22,6 +22,7 @@ import * as ts from 'typescript';
import * as url from 'url';
import * as webpack from 'webpack';
import * as WebpackDevServer from 'webpack-dev-server';
import { normalizeExtraEntryPoints } from '../angular-cli-files/models/webpack-configs/utils';
import { IndexHtmlWebpackPlugin } from '../angular-cli-files/plugins/index-html-webpack-plugin';
import { checkPort } from '../angular-cli-files/utilities/check-port';
import { IndexHtmlTransform } from '../angular-cli-files/utilities/index-file/write-index-html';
Expand Down Expand Up @@ -175,7 +176,7 @@ export function serveWebpackBrowser(

// Add live reload config.
if (options.liveReload) {
_addLiveReload(options, browserOptions, webpackConfig, clientAddress, context.logger);
_addLiveReload(root, options, browserOptions, webpackConfig, clientAddress, context.logger);
} else if (options.hmr) {
context.logger.warn('Live reload is disabled. HMR option ignored.');
}
Expand Down Expand Up @@ -491,6 +492,7 @@ export function buildServePath(
* @private
*/
function _addLiveReload(
root: string,
options: DevServerBuilderOptions,
browserOptions: BrowserBuilderSchema,
webpackConfig: webpack.Configuration,
Expand Down Expand Up @@ -555,28 +557,30 @@ function _addLiveReload(
const entryPoints = [`${webpackDevServerPath}?${url.format(clientAddress)}${sockjsPath}`];
if (options.hmr) {
const webpackHmrLink = 'https://webpack.js.org/guides/hot-module-replacement';

logger.warn(tags.oneLine`NOTICE: Hot Module Replacement (HMR) is enabled for the dev server.`);

const showWarning = options.hmrWarning;
if (showWarning) {
logger.info(tags.stripIndents`
The project will still live reload when HMR is enabled,
but to take advantage of HMR additional application code is required'
(not included in an Angular CLI project by default).'
See ${webpackHmrLink}
for information on working with HMR for Webpack.`);
The project will still live reload when HMR is enabled, but to take full advantage of HMR
additional application code which is not included by default in an Angular CLI project is required.

See ${webpackHmrLink} for information on working with HMR for Webpack.`);
logger.warn(
tags.oneLine`To disable this warning use "hmrWarning: false" under "serve"
options in "angular.json".`,
);
}
entryPoints.push('webpack/hot/dev-server');
webpackConfig.plugins.push(new webpack.HotModuleReplacementPlugin());
if (browserOptions.extractCss) {
logger.warn(tags.oneLine`NOTICE: (HMR) does not allow for CSS hot reload
when used together with '--extract-css'.`);
if (browserOptions.styles?.length) {
// When HMR is enabled we need to add the css paths as part of the entrypoints
// because otherwise no JS bundle will contain the HMR accept code.
const normalizedStyles = normalizeExtraEntryPoints(browserOptions.styles, 'styles')
.map(style => path.resolve(root, style.input));
entryPoints.push(...normalizedStyles);
}

webpackConfig.plugins.push(new webpack.HotModuleReplacementPlugin());
}
if (typeof webpackConfig.entry !== 'object' || Array.isArray(webpackConfig.entry)) {
webpackConfig.entry = {};
Expand Down