Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inline worker code incompatibility with Playwright’s WebKit #19238

Open
7 tasks done
lozinsky opened this issue Jan 20, 2025 · 6 comments
Open
7 tasks done

Inline worker code incompatibility with Playwright’s WebKit #19238

lozinsky opened this issue Jan 20, 2025 · 6 comments
Labels
contribution welcome feat: web workers p3-minor-bug An edge case that only affects very specific usage (priority)

Comments

@lozinsky
Copy link

Describe the bug

The current implementation of inline workers generated by Vite is not compatible with Playwright’s WebKit browser. Specifically, the WorkerWrapper code fails when trying to create workers using a Blob URL in WebKit, leading to errors during tests.

The code in question is as follows:

function WorkerWrapper(options) {
  let objURL;
  try {
    objURL = blob && (self.URL || self.webkitURL).createObjectURL(blob);
    if (!objURL) throw "";
    const worker = new Worker(objURL, {
      name: options == null ? void 0 : options.name
    });
    worker.addEventListener("error", () => {
      (self.URL || self.webkitURL).revokeObjectURL(objURL);
    });
    return worker;
  } catch (e) {
    return new Worker(
      "data:text/javascript;base64," + encodedJs,
      {
        name: options == null ? void 0 : options.name
      }
    );
  } finally {
    objURL && (self.URL || self.webkitURL).revokeObjectURL(objURL);
  }
}

The issue arises because the code attempts to immediately revoke the Blob URL in the finally block:

objURL && (self.URL || self.webkitURL).revokeObjectURL(objURL);

This behavior invalidates the Blob URL before the worker can properly utilize it. Playwright’s WebKit (and likely other WebKit browsers) require the Blob URL to remain valid for the worker’s lifecycle, and prematurely revoking it causes failures. microsoft/playwright#33794 (comment)

What do you think, should it be fixed on the Vite side?

Reproduction

https://github.com/lozinsky/vite-inline-worker-playwright-webkit

Steps to reproduce

No response

System Info

System:
  OS: macOS 15.2
  CPU: (8) arm64 Apple M1 Pro
  Memory: 189.03 MB / 16.00 GB
  Shell: 3.7.1 - /opt/homebrew/bin/fish
Binaries:
  Node: 20.12.2
  npm: 10.5.0
Browsers:
  Chrome: 131.0.6778.265
  Safari: 18.2
npmPackages:
  vite: 6.0.8 => 6.0.8

Used Package Manager

npm

Logs

No response

Validations

@sapphi-red
Copy link
Member

Fixing on Vite side makes sense to me.
Probably calling (self.URL || self.webkitURL).revokeObjectURL(self.location.href); at the top of the worker script for classic workers would work.

`'URL.revokeObjectURL(import.meta.url);',`

@sapphi-red sapphi-red added p3-minor-bug An edge case that only affects very specific usage (priority) feat: web workers contribution welcome labels Jan 23, 2025
@aKzenT
Copy link

aKzenT commented Jan 29, 2025

Having the same problem. Did you find any workaround that we could use until it is fixed? @lozinsky

@lozinsky
Copy link
Author

Did you find any workaround that we could use until it is fixed?

Unfortunately, no 😞

@aKzenT
Copy link

aKzenT commented Jan 30, 2025

@sapphi-red you mentioned adding revokeObjectURL to the worker script of classic workers. In your references code I see that for modern workers the code alredy calls URL.revokeObjectURL(import.meta.url);. Does that mean that the call to revokeObjectURL in the worker wrapper is only necessary for classic workers as modern workers already take care of it themselves?

@sapphi-red
Copy link
Member

@aKzenT
No, I mean the revokeObjectURL call should be removed from the finally clause and called inside the worker code instead, like it's done for the module worker.

@aKzenT
Copy link

aKzenT commented Jan 30, 2025

thanks for the clarification, I didn't realize that "classic" workers are still the default in vite. So although our project was configured for ESM, the workers were not using it. So in my case the 'workarround' is simply to switch to module workers:

    worker: {
        format: 'es',
    },

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
contribution welcome feat: web workers p3-minor-bug An edge case that only affects very specific usage (priority)
Projects
None yet
Development

No branches or pull requests

3 participants