Skip to content

Commit c71e954

Browse files
committedMar 25, 2024
fix(@angular-devkit/build-angular): service-worker references non-existent named index output
This commit addresses an issue where the service worker incorrectly referenced a non-existent `index.html` when utilizing the output index option. Additionally, it ensures proper resolution of the service worker configuration when the option value is set to `true`.
1 parent 31e8ad3 commit c71e954

File tree

4 files changed

+105
-2
lines changed

4 files changed

+105
-2
lines changed
 

‎packages/angular_devkit/build_angular/src/builders/application/execute-post-bundle.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,12 @@ export async function executePostBundleSteps(
153153
workspaceRoot,
154154
serviceWorker,
155155
options.baseHref || '/',
156+
options.indexHtmlOptions?.output,
156157
// Ensure additional files recently added are used
157158
[...outputFiles, ...additionalOutputFiles],
158159
assetFiles,
159160
);
161+
160162
additionalOutputFiles.push(
161163
createOutputFileFromText(
162164
'ngsw.json',

‎packages/angular_devkit/build_angular/src/builders/application/options.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -326,8 +326,12 @@ export async function normalizeOptions(
326326
fileReplacements,
327327
globalStyles,
328328
globalScripts,
329-
serviceWorker:
330-
typeof serviceWorker === 'string' ? path.join(workspaceRoot, serviceWorker) : undefined,
329+
serviceWorker: serviceWorker
330+
? path.join(
331+
workspaceRoot,
332+
typeof serviceWorker === 'string' ? serviceWorker : 'src/ngsw-config.json',
333+
)
334+
: undefined,
331335
indexHtmlOptions,
332336
tailwindConfiguration,
333337
postcssConfiguration,
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC 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+
9+
import { buildApplication } from '../../index';
10+
import { APPLICATION_BUILDER_INFO, BASE_OPTIONS, describeBuilder } from '../setup';
11+
12+
describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => {
13+
describe('Option: "serviceWorker"', () => {
14+
beforeEach(async () => {
15+
const manifest = {
16+
index: '/index.html',
17+
assetGroups: [
18+
{
19+
name: 'app',
20+
installMode: 'prefetch',
21+
resources: {
22+
files: ['/favicon.ico', '/index.html'],
23+
},
24+
},
25+
{
26+
name: 'assets',
27+
installMode: 'lazy',
28+
updateMode: 'prefetch',
29+
resources: {
30+
files: [
31+
'/assets/**',
32+
'/*.(svg|cur|jpg|jpeg|png|apng|webp|avif|gif|otf|ttf|woff|woff2)',
33+
],
34+
},
35+
},
36+
],
37+
};
38+
39+
await harness.writeFile('src/ngsw-config.json', JSON.stringify(manifest));
40+
});
41+
42+
it('should not generate SW config when option is unset', async () => {
43+
harness.useTarget('build', {
44+
...BASE_OPTIONS,
45+
serviceWorker: undefined,
46+
});
47+
48+
const { result } = await harness.executeOnce();
49+
expect(result?.success).toBeTrue();
50+
harness.expectFile('dist/browser/ngsw.json').toNotExist();
51+
});
52+
53+
it('should not generate SW config when option is false', async () => {
54+
harness.useTarget('build', {
55+
...BASE_OPTIONS,
56+
serviceWorker: false,
57+
});
58+
59+
const { result } = await harness.executeOnce();
60+
expect(result?.success).toBeTrue();
61+
harness.expectFile('dist/browser/ngsw.json').toNotExist();
62+
});
63+
64+
it('should generate SW config when option is true', async () => {
65+
harness.useTarget('build', {
66+
...BASE_OPTIONS,
67+
serviceWorker: true,
68+
});
69+
70+
const { result } = await harness.executeOnce();
71+
expect(result?.success).toBeTrue();
72+
harness.expectFile('dist/browser/ngsw.json').toExist();
73+
});
74+
75+
it('should generate SW config referencing index output', async () => {
76+
harness.useTarget('build', {
77+
...BASE_OPTIONS,
78+
serviceWorker: true,
79+
index: {
80+
input: 'src/index.html',
81+
output: 'index.csr.html',
82+
},
83+
});
84+
85+
const { result } = await harness.executeOnce();
86+
expect(result?.success).toBe(true);
87+
88+
const config = await harness.readFile('dist/browser/ngsw.json');
89+
expect(JSON.parse(config)).toEqual(jasmine.objectContaining({ index: '/index.csr.html' }));
90+
});
91+
});
92+
});

‎packages/angular_devkit/build_angular/src/utils/service-worker.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ export async function augmentAppWithServiceWorkerEsbuild(
180180
workspaceRoot: string,
181181
configPath: string,
182182
baseHref: string,
183+
indexHtml: string | undefined,
183184
outputFiles: BuildOutputFile[],
184185
assetFiles: BuildOutputAsset[],
185186
): Promise<{ manifest: string; assetFiles: BuildOutputAsset[] }> {
@@ -188,6 +189,10 @@ export async function augmentAppWithServiceWorkerEsbuild(
188189
try {
189190
const configurationData = await fsPromises.readFile(configPath, 'utf-8');
190191
config = JSON.parse(configurationData) as Config;
192+
193+
if (indexHtml) {
194+
config.index = indexHtml;
195+
}
191196
} catch (error) {
192197
assertIsError(error);
193198
if (error.code === 'ENOENT') {

0 commit comments

Comments
 (0)
Please sign in to comment.