Skip to content

Commit b4bfa86

Browse files
committed
fix(@angular/build): avoid internal karma request cache for assets
The internal karma common middleware that handles requests converts the to be cached data into a string when stored. This can lead to invalid data when the cached string is then sent in a followup request if the original content was not intended to be a string. To avoid this problem, asset files are now explicitly not cached by karma's middleware. Ref: https://github.com/karma-runner/karma/blob/84f85e7016efc2266fa6b3465f494a3fa151c85c/lib/middleware/common.js#L72
1 parent 23124c5 commit b4bfa86

File tree

2 files changed

+70
-1
lines changed

2 files changed

+70
-1
lines changed

packages/angular/build/src/builders/karma/application_builder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class AngularAssetsMiddleware {
8686

8787
switch (file.origin) {
8888
case 'disk':
89-
this.serveFile(file.inputPath, undefined, res);
89+
this.serveFile(file.inputPath, undefined, res, undefined, undefined, /* doNotCache */ true);
9090
break;
9191
case 'memory':
9292
// Include pathname to help with Content-Type headers.

packages/angular/build/src/builders/karma/tests/behavior/rebuilds_spec.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,5 +68,74 @@ describeKarmaBuilder(execute, KARMA_BUILDER_INFO, (harness, setupTarget) => {
6868

6969
expect(buildCount).toBe(expectedSequence.length);
7070
});
71+
72+
it('correctly serves binary assets on rebuilds', async () => {
73+
/**
74+
* Compiled and base64 encoded WASM file for the following WAT:
75+
* ```
76+
* (module
77+
* (export "multiply" (func $multiply))
78+
* (func $multiply (param i32 i32) (result i32)
79+
* local.get 0
80+
* local.get 1
81+
* i32.mul
82+
* )
83+
* )
84+
* ```
85+
*/
86+
const exportWasmBase64 =
87+
'AGFzbQEAAAABBwFgAn9/AX8DAgEABwwBCG11bHRpcGx5AAAKCQEHACAAIAFsCwAXBG5hbWUBCwEACG11bHRpcGx5AgMBAAA=';
88+
await harness.writeFiles({
89+
'./src/multiply.wasm': Buffer.from(exportWasmBase64, 'base64'),
90+
'./src/app/app.component.spec.ts': `
91+
describe('AppComponent', () => {
92+
it('should fetch WASM file with correct size', async () => {
93+
const resp = await fetch('/multiply.wasm');
94+
const data = await resp.arrayBuffer();
95+
expect(data.byteLength).toBe(71);
96+
});
97+
});`,
98+
});
99+
100+
harness.useTarget('test', {
101+
...BASE_OPTIONS,
102+
watch: true,
103+
assets: ['src/multiply.wasm'],
104+
});
105+
106+
interface OutputCheck {
107+
(result: BuilderOutput | undefined): Promise<void>;
108+
}
109+
110+
const expectedSequence: OutputCheck[] = [
111+
async (result) => {
112+
// Karma run should succeed.
113+
expect(result?.success).withContext('Initial test run should succeed').toBeTrue();
114+
// Modify test file to trigger a rebuild
115+
await harness.appendToFile(
116+
'src/app/app.component.spec.ts',
117+
`\n;console.log('modified');`,
118+
);
119+
},
120+
async (result) => {
121+
expect(result?.success).withContext('Test should succeed again').toBeTrue();
122+
},
123+
];
124+
125+
const buildCount = await harness
126+
.execute({ outputLogsOnFailure: true })
127+
.pipe(
128+
timeout(60000),
129+
debounceTime(500),
130+
concatMap(async ({ result }, index) => {
131+
await expectedSequence[index](result);
132+
}),
133+
take(expectedSequence.length),
134+
count(),
135+
)
136+
.toPromise();
137+
138+
expect(buildCount).toBe(expectedSequence.length);
139+
});
71140
});
72141
});

0 commit comments

Comments
 (0)