Skip to content

Commit 72f53c2

Browse files
committed
fix(@angular-devkit/build-angular): don't add hash to lazy styles
Fix #11235
1 parent 773984d commit 72f53c2

File tree

3 files changed

+74
-1
lines changed

3 files changed

+74
-1
lines changed

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

+14-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { findUp } from '../../utilities/find-up';
1717
import { RawCssLoader } from '../../plugins/webpack';
1818
import { ExtraEntryPoint } from '../../../browser/schema';
1919
import { normalizeExtraEntryPoints } from './utils';
20+
import { RemoveHashPlugin } from '../../plugins/remove-hash-plugin';
2021

2122
const postcssUrl = require('postcss-url');
2223
const autoprefixer = require('autoprefixer');
@@ -158,7 +159,7 @@ export function getStylesConfig(wco: WebpackConfigOptions) {
158159

159160
// use includePaths from appConfig
160161
const includePaths: string[] = [];
161-
let lessPathOptions: { paths?: string[] } = { };
162+
let lessPathOptions: { paths?: string[] } = {};
162163

163164
if (buildOptions.stylePreprocessorOptions
164165
&& buildOptions.stylePreprocessorOptions.includePaths
@@ -173,6 +174,8 @@ export function getStylesConfig(wco: WebpackConfigOptions) {
173174

174175
// Process global styles.
175176
if (buildOptions.styles.length > 0) {
177+
const chunkIds: string[] = [];
178+
176179
normalizeExtraEntryPoints(buildOptions.styles, 'styles').forEach(style => {
177180
const resolvedPath = path.resolve(root, style.input);
178181

@@ -183,9 +186,19 @@ export function getStylesConfig(wco: WebpackConfigOptions) {
183186
entryPoints[style.bundleName] = [resolvedPath]
184187
}
185188

189+
// Add lazy styles to the list.
190+
if (style.lazy) {
191+
chunkIds.push(style.bundleName);
192+
}
193+
186194
// Add global css paths.
187195
globalStylePaths.push(resolvedPath);
188196
});
197+
198+
if (chunkIds.length > 0) {
199+
// Add plugin to remove hashes from lazy styles.
200+
extraPlugins.push(new RemoveHashPlugin({ chunkIds, hashFormat}));
201+
}
189202
}
190203

191204
// set base rules to derive final rules from
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
import { Compiler, compilation } from 'webpack';
9+
import { HashFormat } from '../models/webpack-configs/utils';
10+
11+
12+
export interface RemoveHashPluginOptions {
13+
chunkIds: string[];
14+
hashFormat: HashFormat;
15+
}
16+
17+
export class RemoveHashPlugin {
18+
19+
constructor(private options: RemoveHashPluginOptions) { }
20+
21+
apply(compiler: Compiler): void {
22+
compiler.hooks.compilation.tap('remove-hash-plugin', compilation => {
23+
const mainTemplate = compilation.mainTemplate as compilation.MainTemplate & {
24+
hooks: compilation.CompilationHooks;
25+
};
26+
27+
mainTemplate.hooks.assetPath.tap('remove-hash-plugin',
28+
(path: string, data: { chunk?: { id: string } }) => {
29+
const chunkId = data.chunk && data.chunk.id;
30+
31+
if (chunkId && this.options.chunkIds.includes(chunkId)) {
32+
// Replace hash formats with empty strings.
33+
return path
34+
.replace(this.options.hashFormat.chunk, '')
35+
.replace(this.options.hashFormat.extract, '');
36+
}
37+
38+
return path;
39+
},
40+
);
41+
});
42+
}
43+
}

packages/angular_devkit/build_angular/test/browser/output-hashing_spec_large.ts

+17
Original file line numberDiff line numberDiff line change
@@ -163,4 +163,21 @@ describe('Browser Builder output hashing', () => {
163163
}),
164164
).toPromise().then(done, done.fail);
165165
});
166+
167+
it('does not hash lazy styles', (done) => {
168+
const overrides = {
169+
outputHashing: 'all',
170+
extractCss: true,
171+
styles: [{ input: 'src/styles.css', lazy: true }],
172+
};
173+
174+
runTargetSpec(host, browserTargetSpec, overrides, DefaultTimeout).pipe(
175+
tap(() => {
176+
expect(host.fileMatchExists('dist', /styles\.[0-9a-f]{20}\.js/)).toBeFalsy();
177+
expect(host.fileMatchExists('dist', /styles\.[0-9a-f]{20}\.js.map/)).toBeFalsy();
178+
expect(host.scopedSync().exists(normalize('dist/styles.css'))).toBe(true);
179+
expect(host.scopedSync().exists(normalize('dist/styles.css.map'))).toBe(true);
180+
}),
181+
).toPromise().then(done, done.fail);
182+
});
166183
});

0 commit comments

Comments
 (0)