iislucas
iislucas

Reputation: 359

How to specify the URL for a webworker in an Angular 17 or 18 test (using karma-chrome-launcher & jasmine)

What's the right way in an angular test to provide the URL for a webworker? e.g.

In a component.spec.ts file, I'd like to be able to write:

const worker = new Worker(workerUrl, options);

But I'm not sure what workerUrl to provide.

My understanding of using webworkers in Angular (documentation link) is that you should do the following (which I've done):

  1. new Worker(new URL(relativeWorkerPath, import.meta.url)); where relativeWorkerPath is a string that represents the relative path from the current typescript file to the webworker file (without the postfix).

  2. Create a tsconfig.worker.json at your project root level with the other tsconfig files, something like so:

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/worker",
    "lib": [
      "ESNext",
      "webworker"
    ],
  },
  "include": [
    "src/**/*.worker.ts"
  ]
}
  1. Add an option "webWorkerTsConfig": "tsconfig.worker.json", to every build section, something like so:
{ ...
  "projects": {
    "YOUR PROJECT NAME": { ...
      "architect": {
        "THE BUILD TYPE; EITHER `build`, `serve`, or `test`": {
          "builder": "THE BUILDER",
          "options": {
            ...
            "webWorkerTsConfig": "tsconfig.worker.json",
 ...
}
  1. Create your webworker in a file in your src directory somewhere with a filename that ends in .worker.ts.

This works when I build the code (running ng build) or use the development server (running ng serve), but for tests it does not work because it tries to load the webworker from a path of the form: file:///.../example.worker.

What's the right way to reference paths to webworkers so they work in tests?

I think angular is using karma-webpack and karma-chrome-launcher under the hood, so maybe there's some config of those needed?

Upvotes: 1

Views: 250

Answers (1)

iislucas
iislucas

Reputation: 359

In Angular 18 (and likely earlier), the following does not work in karma test:

const workerUrl = new URL('./foo.worker', import.meta.url);
const worker = new Worker(workerUrl);

But this does:

const worker = new Worker(new URL('./foo.worker', import.meta.url));

My guess is some regexp monkeying is happening in the build process to turn './foo.worker' into the build-systems name with a hash value at the end. And if you try and separate the assignment from the new Worker call, the regexp doesn't work, and you then can't find your filename.

So, you have to keep the string together, with no intermediate variable assignments, i.e.:

new Worker(new URL('./foo.worker', import.meta.url));

Upvotes: 0

Related Questions