Skip to content

Commit 0b19406

Browse files
committed
test(@angular-devkit/build-angular): test worker bundling
1 parent 7d52648 commit 0b19406

File tree

4 files changed

+149
-0
lines changed

4 files changed

+149
-0
lines changed

Diff for: packages/angular_devkit/build_angular/src/browser/schema.d.ts

+5
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,11 @@ export interface BrowserBuilderSchema {
194194
*/
195195
serviceWorker: boolean;
196196

197+
/**
198+
* Automatically bundle new Worker('..', { type:'module' }).
199+
*/
200+
autoBundleWorkerModules: boolean;
201+
197202
/**
198203
* Path to ngsw-config.json.
199204
*/

Diff for: packages/angular_devkit/build_angular/src/browser/schema.json

+5
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,11 @@
255255
"description": "Generates a service worker config for production builds.",
256256
"default": false
257257
},
258+
"autoBundleWorkerModules": {
259+
"type": "boolean",
260+
"description": "Automatically bundle new Worker('..', { type:'module' })",
261+
"default": true
262+
},
258263
"ngswConfigPath": {
259264
"type": "string",
260265
"description": "Path to ngsw-config.json."
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. 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 { runTargetSpec } from '@angular-devkit/architect/testing';
10+
import { join, virtualFs } from '@angular-devkit/core';
11+
import { tap } from 'rxjs/operators';
12+
import { browserTargetSpec, host, outputPath } from '../utils';
13+
14+
15+
describe('Browser Builder bundle worker', () => {
16+
beforeEach(done => host.initialize().toPromise().then(done, done.fail));
17+
// afterEach(done => host.restore().toPromise().then(done, done.fail));
18+
19+
const workerFiles = {
20+
'src/dep.js': `export const foo = 'bar';`,
21+
'src/worker.js': `
22+
import { foo } from './dep';
23+
24+
console.log('hello from worker');
25+
26+
addEventListener('message', ({ data }) => {
27+
console.log('worker got message:', data);
28+
if (data === 'hello') {
29+
postMessage(foo);
30+
}
31+
});
32+
`,
33+
'src/main.ts': `
34+
const worker = new Worker('./worker', { type: 'module' });
35+
worker.onmessage = ({ data }) => {
36+
console.log('page got message:', data);
37+
};
38+
worker.postMessage('hello');
39+
`,
40+
};
41+
42+
describe('js workers', () => {
43+
it('bundles worker', (done) => {
44+
host.writeMultipleFiles(workerFiles);
45+
const overrides = { autoBundleWorkerModules: true };
46+
runTargetSpec(host, browserTargetSpec, overrides).pipe(
47+
tap((buildEvent) => expect(buildEvent.success).toBe(true)),
48+
tap(() => {
49+
const workerContent = virtualFs.fileBufferToString(
50+
host.scopedSync().read(join(outputPath, '0.worker.js')),
51+
);
52+
// worker bundle contains worker code.
53+
expect(workerContent).toContain('hello from worker');
54+
expect(workerContent).toContain('bar');
55+
56+
const mainContent = virtualFs.fileBufferToString(
57+
host.scopedSync().read(join(outputPath, 'main.js')),
58+
);
59+
// main bundle references worker.
60+
expect(mainContent).toContain('0.worker.js');
61+
}),
62+
).toPromise().then(done, done.fail);
63+
});
64+
65+
it('minimizes and hashes worker', (done) => {
66+
host.writeMultipleFiles(workerFiles);
67+
const overrides = { autoBundleWorkerModules: true, outputHashing: 'all', optimization: true };
68+
runTargetSpec(host, browserTargetSpec, overrides).pipe(
69+
tap((buildEvent) => expect(buildEvent.success).toBe(true)),
70+
tap(() => {
71+
const workerBundle = host.fileMatchExists(outputPath,
72+
/0\.[0-9a-f]{20}\.worker\.js/) as string;
73+
expect(workerBundle).toBeTruthy('workerBundle should exist');
74+
const workerContent = virtualFs.fileBufferToString(
75+
host.scopedSync().read(join(outputPath, workerBundle)),
76+
);
77+
expect(workerContent).toContain('hello from worker');
78+
expect(workerContent).toContain('bar');
79+
expect(workerContent).toContain('"hello"===e&&postMessage("bar")');
80+
81+
const mainBundle = host.fileMatchExists(outputPath, /main\.[0-9a-f]{20}\.js/) as string;
82+
expect(mainBundle).toBeTruthy('mainBundle should exist');
83+
const mainContent = virtualFs.fileBufferToString(
84+
host.scopedSync().read(join(outputPath, mainBundle)),
85+
);
86+
expect(mainContent).toContain(workerBundle);
87+
}),
88+
).toPromise().then(done, done.fail);
89+
});
90+
});
91+
});

Diff for: tests/legacy-cli/e2e/tests/misc/bundle-worker.ts

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { writeMultipleFiles } from '../../utils/fs';
2+
import { ng } from '../../utils/process';
3+
4+
5+
export default async function () {
6+
// console.warn has to be used because chrome only captures warnings and errors by default
7+
// https://github.com/angular/protractor/issues/2207
8+
await writeMultipleFiles({
9+
'./src/dep.js': `export const foo = 'bar';`,
10+
'./src/worker.js': `
11+
import { foo } from './dep';
12+
13+
console.log('hello from worker');
14+
15+
addEventListener('message', ({ data }) => {
16+
console.log('worker got message:', data);
17+
if (data === 'hello') {
18+
postMessage(foo);
19+
}
20+
});
21+
`,
22+
'./src/main.ts': `
23+
const worker = new Worker('./worker', { type: 'module' });
24+
worker.onmessage = ({ data }) => {
25+
console.log('page got message:', data);
26+
};
27+
worker.postMessage('hello');
28+
`,
29+
'./e2e/app.e2e-spec.ts': `
30+
import { browser, element, by } from 'protractor';
31+
32+
describe('worker bundle', function() {
33+
it('should log worker messages', () => {
34+
browser.ignoreSynchronization = true;
35+
browser.get('/');
36+
browser.sleep(5000)
37+
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
38+
expect(logs.length).toEqual(3);
39+
expect(logs[0].message).toContain('hello from worker');
40+
expect(logs[1].message).toContain('worker got message: hello');
41+
expect(logs[2].message).toContain('page got data: foo');
42+
});
43+
});
44+
`,
45+
});
46+
47+
await ng('e2e');
48+
}

0 commit comments

Comments
 (0)