Skip to content

Commit 5855374

Browse files
alan-agius4clydin
authored andcommitted
fix(@ngtools/webpack): re-emit component stylesheet assets
With this change we re-emit assets referenced in component stylesheets which where uneffected by the change that re-triggered a re-compilation. Since we cache the the result of processed component CSS, during a re-compilation `postcss-cli-resources` plugin will not run which causes assets to be to emit. With this change we now cache the asset and re-emit them on every change. Closes #20882
1 parent 1ab2ef9 commit 5855374

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

packages/angular_devkit/build_angular/src/webpack/plugins/postcss-cli-resources.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ export default function (options?: PostcssCliResourcesOptions): Plugin {
125125

126126
loader.addDependency(result);
127127
if (emitFile) {
128-
loader.emitFile(outputPath, content, undefined);
128+
loader.emitFile(outputPath, content, undefined, { sourceFilename: result });
129129
}
130130

131131
let outputUrl = outputPath.replace(/\\/g, '/');

packages/ngtools/webpack/src/resource_loader.ts

+31-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import { createHash } from 'crypto';
1010
import * as path from 'path';
1111
import * as vm from 'vm';
12-
import { Compilation, EntryPlugin, NormalModule, library, node, sources } from 'webpack';
12+
import { Asset, Compilation, EntryPlugin, NormalModule, library, node, sources } from 'webpack';
1313
import { normalizePath } from './ivy/paths';
1414

1515
interface CompilationOutput {
@@ -25,13 +25,16 @@ export class WebpackResourceLoader {
2525

2626
private fileCache?: Map<string, CompilationOutput>;
2727
private inlineCache?: Map<string, CompilationOutput>;
28+
private assetCache?: Map<string, Asset>;
29+
2830
private modifiedResources = new Set<string>();
2931
private outputPathCounter = 1;
3032

3133
constructor(shouldCache: boolean) {
3234
if (shouldCache) {
3335
this.fileCache = new Map();
3436
this.inlineCache = new Map();
37+
this.assetCache = new Map();
3538
}
3639
}
3740

@@ -40,15 +43,34 @@ export class WebpackResourceLoader {
4043

4144
// Update resource cache and modified resources
4245
this.modifiedResources.clear();
46+
4347
if (changedFiles) {
4448
for (const changedFile of changedFiles) {
49+
const changedFileNormalized = normalizePath(changedFile);
50+
this.assetCache?.delete(changedFileNormalized);
51+
4552
for (const affectedResource of this.getAffectedResources(changedFile)) {
46-
this.fileCache?.delete(normalizePath(affectedResource));
53+
const affectedResourceNormalized = normalizePath(affectedResource);
54+
this.fileCache?.delete(affectedResourceNormalized);
4755
this.modifiedResources.add(affectedResource);
56+
57+
for (const effectedDependencies of this.getResourceDependencies(
58+
affectedResourceNormalized,
59+
)) {
60+
this.assetCache?.delete(normalizePath(effectedDependencies));
61+
}
4862
}
4963
}
5064
} else {
5165
this.fileCache?.clear();
66+
this.assetCache?.clear();
67+
}
68+
69+
// Re-emit all assets for un-effected files
70+
if (this.assetCache) {
71+
for (const [, { name, source, info }] of this.assetCache) {
72+
this._parentCompilation.emitAsset(name, source, info);
73+
}
5274
}
5375
}
5476

@@ -200,6 +222,13 @@ export class WebpackResourceLoader {
200222

201223
parent.warnings.push(...childCompilation.warnings);
202224
parent.errors.push(...childCompilation.errors);
225+
for (const { info, name, source } of childCompilation.getAssets()) {
226+
if (info.sourceFilename === undefined) {
227+
throw new Error(`'${name}' asset info 'sourceFilename' is 'undefined'.`);
228+
}
229+
230+
this.assetCache?.set(info.sourceFilename, { info, name, source });
231+
}
203232
}
204233

205234
// Save the dependencies for this resource.

0 commit comments

Comments
 (0)