Skip to content

Commit 75d332b

Browse files
committed
fix(@angular-devkit/build-angular): handle service-worker serving with localize in dev-server
Previously, we tried to read the files from the wrong location as during localize we alter the output directory to a different temporary location. https://github.com/angular/angular-cli/blob/7e64b1537d54fadb650559214fbb12707324cd75/packages/angular_devkit/build_angular/src/utils/i18n-options.ts#L251-L252 Closes #23844
1 parent 7e64b15 commit 75d332b

File tree

3 files changed

+89
-4
lines changed

3 files changed

+89
-4
lines changed

packages/angular_devkit/build_angular/src/builders/dev-server/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,6 @@ export function serveWebpackBrowser(
242242
baseHref: browserOptions.baseHref,
243243
root: context.workspaceRoot,
244244
projectRoot,
245-
outputPath: path.join(context.workspaceRoot, browserOptions.outputPath),
246245
ngswConfigPath: browserOptions.ngswConfigPath,
247246
}),
248247
);

packages/angular_devkit/build_angular/src/builders/dev-server/tests/behavior/serve_service-worker_spec.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,86 @@ describeBuilder(serveWebpackBrowser, DEV_SERVER_BUILDER_INFO, (harness) => {
106106
);
107107
});
108108

109+
it('works with localize', async () => {
110+
harness.useProject('test', {
111+
root: '.',
112+
sourceRoot: 'src',
113+
cli: {
114+
cache: {
115+
enabled: false,
116+
},
117+
},
118+
i18n: {
119+
sourceLocale: {
120+
'code': 'fr',
121+
},
122+
},
123+
});
124+
125+
setupBrowserTarget(harness, {
126+
serviceWorker: true,
127+
assets: ['src/favicon.ico', 'src/assets'],
128+
styles: ['src/styles.css'],
129+
localize: ['fr'],
130+
});
131+
132+
await harness.writeFiles({
133+
'ngsw-config.json': JSON.stringify(manifest),
134+
'src/assets/folder-asset.txt': 'folder-asset.txt',
135+
'src/styles.css': `body { background: url(./spectrum.png); }`,
136+
});
137+
138+
harness.useTarget('serve', {
139+
...BASE_OPTIONS,
140+
});
141+
142+
const { result, response } = await executeOnceAndFetch(harness, '/ngsw.json');
143+
144+
expect(result?.success).toBeTrue();
145+
146+
expect(await response?.json()).toEqual(
147+
jasmine.objectContaining({
148+
configVersion: 1,
149+
index: '/index.html',
150+
navigationUrls: [
151+
{ positive: true, regex: '^\\/.*$' },
152+
{ positive: false, regex: '^\\/(?:.+\\/)?[^/]*\\.[^/]*$' },
153+
{ positive: false, regex: '^\\/(?:.+\\/)?[^/]*__[^/]*$' },
154+
{ positive: false, regex: '^\\/(?:.+\\/)?[^/]*__[^/]*\\/.*$' },
155+
],
156+
assetGroups: [
157+
{
158+
name: 'app',
159+
installMode: 'prefetch',
160+
updateMode: 'prefetch',
161+
urls: ['/favicon.ico', '/index.html'],
162+
cacheQueryOptions: {
163+
ignoreVary: true,
164+
},
165+
patterns: [],
166+
},
167+
{
168+
name: 'assets',
169+
installMode: 'lazy',
170+
updateMode: 'prefetch',
171+
urls: ['/assets/folder-asset.txt', '/spectrum.png'],
172+
cacheQueryOptions: {
173+
ignoreVary: true,
174+
},
175+
patterns: [],
176+
},
177+
],
178+
dataGroups: [],
179+
hashTable: {
180+
'/favicon.ico': '84161b857f5c547e3699ddfbffc6d8d737542e01',
181+
'/assets/folder-asset.txt': '617f202968a6a81050aa617c2e28e1dca11ce8d4',
182+
'/index.html': '9d232e3e13b4605d197037224a2a6303dd337480',
183+
'/spectrum.png': '8d048ece46c0f3af4b598a95fd8e4709b631c3c0',
184+
},
185+
}),
186+
);
187+
});
188+
109189
it('works in watch mode', async () => {
110190
setupBrowserTarget(harness, {
111191
serviceWorker: true,

packages/angular_devkit/build_angular/src/webpack/plugins/service-worker-plugin.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { augmentAppWithServiceWorker } from '../../utils/service-worker';
1212
export interface ServiceWorkerPluginOptions {
1313
projectRoot: string;
1414
root: string;
15-
outputPath: string;
1615
baseHref?: string;
1716
ngswConfigPath?: string;
1817
}
@@ -21,8 +20,15 @@ export class ServiceWorkerPlugin {
2120
constructor(private readonly options: ServiceWorkerPluginOptions) {}
2221

2322
apply(compiler: Compiler) {
24-
compiler.hooks.done.tapPromise('angular-service-worker', async (_compilation) => {
25-
const { projectRoot, root, baseHref = '', ngswConfigPath, outputPath } = this.options;
23+
compiler.hooks.done.tapPromise('angular-service-worker', async ({ compilation }) => {
24+
const { projectRoot, root, baseHref = '', ngswConfigPath } = this.options;
25+
// We use the outputPath from the compilation instead of build-options since during
26+
// localization the output path is modified to a tmp directory.
27+
const outputPath = compilation.outputOptions.path;
28+
29+
if (!outputPath) {
30+
throw new Error('Compilation output path cannot be empty.');
31+
}
2632

2733
await augmentAppWithServiceWorker(
2834
projectRoot,

0 commit comments

Comments
 (0)