Skip to content

Commit b79b941

Browse files
filipesilvahansl
authored andcommitted
fix(@angular-devkit/build-angular): fix service worker assets paths
Fix #10297
1 parent 646336e commit b79b941

File tree

2 files changed

+89
-7
lines changed

2 files changed

+89
-7
lines changed

packages/angular_devkit/build_angular/src/angular-cli-files/utilities/service-worker/index.ts

+19-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
// tslint:disable
22
// TODO: cleanup this file, it's copied as is from Angular CLI.
3-
import { Path, join, normalize, virtualFs, dirname, getSystemPath, tags } from '@angular-devkit/core';
3+
import { Path, join, normalize, virtualFs, dirname, getSystemPath, tags, fragment } from '@angular-devkit/core';
44
import { Filesystem } from '@angular/service-worker/config';
55
import * as crypto from 'crypto';
66
import * as fs from 'fs';
77
import * as semver from 'semver';
88

99
import { resolveProjectModule } from '../require-project-module';
10-
import { map, reduce, switchMap } from "rxjs/operators";
11-
import { Observable, merge, of } from "rxjs";
10+
import { map, reduce, switchMap, concatMap, mergeMap, toArray, tap } from "rxjs/operators";
11+
import { Observable, merge, of, from } from "rxjs";
1212

1313

1414
export const NEW_SW_VERSION = '5.0.0-rc.0';
@@ -18,7 +18,22 @@ class CliFilesystem implements Filesystem {
1818
constructor(private _host: virtualFs.Host, private base: string) { }
1919

2020
list(path: string): Promise<string[]> {
21-
return this._host.list(this._resolve(path)).toPromise().then(x => x, _err => []);
21+
const recursiveList = (path: Path): Observable<Path> => this._host.list(path).pipe(
22+
// Emit each fragment individually.
23+
concatMap(fragments => from(fragments)),
24+
// Join the path with fragment.
25+
map(fragment => join(path, fragment)),
26+
// Emit directory content paths instead of the directory path.
27+
mergeMap(path => this._host.isDirectory(path).pipe(
28+
concatMap(isDir => isDir ? recursiveList(path) : of(path))
29+
)
30+
),
31+
);
32+
33+
return recursiveList(this._resolve(path)).pipe(
34+
map(path => path.replace(this.base, '')),
35+
toArray(),
36+
).toPromise().then(x => x, _err => []);
2237
}
2338

2439
read(path: string): Promise<string> {

packages/angular_devkit/build_angular/test/browser/service-worker_spec_large.ts

+70-3
Original file line numberDiff line numberDiff line change
@@ -53,30 +53,97 @@ describe('Browser Builder', () => {
5353
it('works with service worker', (done) => {
5454
host.writeMultipleFiles({
5555
'src/ngsw-config.json': JSON.stringify(manifest),
56+
'src/assets/folder-asset.txt': 'folder-asset.txt',
5657
});
5758

5859
const overrides = { serviceWorker: true };
5960
runTargetSpec(host, browserTargetSpec, overrides).pipe(
6061
tap(buildEvent => {
6162
expect(buildEvent.success).toBe(true);
6263
expect(host.scopedSync().exists(normalize('dist/ngsw.json')));
64+
const ngswJson = JSON.parse(virtualFs.fileBufferToString(
65+
host.scopedSync().read(normalize('dist/ngsw.json'))));
66+
// Verify index and assets are there.
67+
expect(ngswJson).toEqual({
68+
configVersion: 1,
69+
index: '/index.html',
70+
assetGroups: [
71+
{
72+
name: 'app',
73+
installMode: 'prefetch',
74+
updateMode: 'prefetch',
75+
urls: [
76+
'/favicon.ico',
77+
'/index.html',
78+
],
79+
patterns: [],
80+
},
81+
{
82+
name: 'assets',
83+
installMode: 'lazy',
84+
updateMode: 'prefetch',
85+
urls: [
86+
'/assets/folder-asset.txt',
87+
],
88+
patterns: [],
89+
},
90+
],
91+
dataGroups: [],
92+
hashTable: {
93+
'/favicon.ico': '460fcbd48b20fcc32b184388606af1238c890dba',
94+
'/assets/folder-asset.txt': '617f202968a6a81050aa617c2e28e1dca11ce8d4',
95+
'/index.html': '3e659d6e536916b7d178d02a2e6e5492f868bf68',
96+
},
97+
});
6398
}),
6499
).subscribe(undefined, done.fail, done);
65100
}, Timeout.Basic);
66101

67102
it('works with service worker and baseHref', (done) => {
68103
host.writeMultipleFiles({
69104
'src/ngsw-config.json': JSON.stringify(manifest),
105+
'src/assets/folder-asset.txt': 'folder-asset.txt',
70106
});
71107

72108
const overrides = { serviceWorker: true, baseHref: '/foo/bar' };
73109
runTargetSpec(host, browserTargetSpec, overrides).pipe(
74110
tap(buildEvent => {
75111
expect(buildEvent.success).toBe(true);
76112
expect(host.scopedSync().exists(normalize('dist/ngsw.json')));
77-
expect(virtualFs.fileBufferToString(
78-
host.scopedSync().read(normalize('dist/ngsw.json')),
79-
)).toMatch(/"\/foo\/bar\/index.html"/);
113+
const ngswJson = JSON.parse(virtualFs.fileBufferToString(
114+
host.scopedSync().read(normalize('dist/ngsw.json'))));
115+
// Verify index and assets include the base href.
116+
expect(ngswJson).toEqual({
117+
configVersion: 1,
118+
index: '/foo/bar/index.html',
119+
assetGroups: [
120+
{
121+
name: 'app',
122+
installMode: 'prefetch',
123+
updateMode: 'prefetch',
124+
urls: [
125+
'/foo/bar/favicon.ico',
126+
'/foo/bar/index.html',
127+
],
128+
patterns: [],
129+
},
130+
{
131+
name: 'assets',
132+
installMode: 'lazy',
133+
updateMode: 'prefetch',
134+
urls: [
135+
'/foo/bar/assets/folder-asset.txt',
136+
],
137+
patterns: [],
138+
},
139+
],
140+
dataGroups: [],
141+
hashTable: {
142+
'/foo/bar/favicon.ico': '460fcbd48b20fcc32b184388606af1238c890dba',
143+
'/foo/bar/assets/folder-asset.txt': '617f202968a6a81050aa617c2e28e1dca11ce8d4',
144+
'/foo/bar/index.html': '5b53fa9e07e4111b8ef84613fb989a56fee502b0',
145+
},
146+
});
80147
}),
81148
).subscribe(undefined, done.fail, done);
82149
}, Timeout.Basic);

0 commit comments

Comments
 (0)