Open Arzaroth opened 1 year ago
Start a new pull request in StackBlitz Codeflow.
This is happening because Workers are always fetched with requestMode="same-origin" (https://github.com/whatwg/html/pull/3656#:~:text=The%20top%2Dlevel%20script%20for%20module%20workers%20is%20always%20fetched%20with%20request%20mode%20%22same%2Dorigin%22%20and%0Acredentials%20mode%20%22same%2Dorigin%22.%20Cross%2Dorigin%20workers%20did%20not%20quite%20work%20due%20to%20service%20workers).
The current workaround is to use this constructor:
import workerUrl from './worker.js?worker&url'
const js = `import ${JSON.stringify(new URL(workerUrl, import.meta.url))}`
const blob = new Blob([js], { type: "application/javascript" })
function WorkaroundWorker(options) {
const objURL = URL.createObjectURL(blob)
const worker = new Worker(objURL, { type: "module", name: options?.name })
worker.addEventListener("error", (e) => {
URL.revokeObjectURL(objURL)
})
return worker;
}
It seems we cannot simply include the code above in Vite. This will change the baseURI (self.location.href
) to be null
.
Indeed the proposed workaround does work. When I tried the Blob trick I was doing it on the worker code itself, I hadn't considered doing it on an import statement instead. Pretty neat! I can even wrap it with Comlink.
I don't know if this warrants a change in Vite itself then. It all happens because I'm running dev mode for a library loaded by a backend on another URL, which seems to be a marginal use case.
Thanks.
@sapphi-red your workaround works ! thanks
@sapphi-red your workaround works ! thanks
Please, can I get an example how to use above workaround
This is happening because Workers are always fetched with requestMode="same-origin" (whatwg/html#3656).
new Worker
hascredentials
option, but IIUC it is disabled.The current workaround is to use this constructor:
import workerUrl from './worker.js?worker&url' const js = `import ${JSON.stringify(new URL(workerUrl, import.meta.url))}` const blob = new Blob([js], { type: "application/javascript" }) function WorkaroundWorker(options) { const objURL = URL.createObjectURL(blob) const worker = new Worker(objURL, { type: "module", name: options?.name }) worker.addEventListener("error", (e) => { URL.revokeObjectURL(objURL) }) return worker; }
please can we get an small example?
This is happening because Workers are always fetched with requestMode="same-origin" (whatwg/html#3656).
new Worker
hascredentials
option, but IIUC it is disabled.The current workaround is to use this constructor:
import workerUrl from './worker.js?worker&url' const js = `import ${JSON.stringify(new URL(workerUrl, import.meta.url))}` const blob = new Blob([js], { type: "application/javascript" }) function WorkaroundWorker(options) { const objURL = URL.createObjectURL(blob) const worker = new Worker(objURL, { type: "module", name: options?.name }) worker.addEventListener("error", (e) => { URL.revokeObjectURL(objURL) }) return worker; }
Useful, thanks
@shubh46
Please, can I get an example how to use above workaround
Monaco Editor + MySQL worker + Vite example:
// userWorker.ts
import workerUrl from "monaco-sql-languages/esm/languages/mysql/mysql.worker.js?worker&url";
// import the worker you need and don't forget about this tail ^^^^^^^^^
const js = `import ${JSON.stringify(new URL(workerUrl, import.meta.url))}`;
const blob = new Blob([js], { type: "application/javascript" });
function WorkaroundWorker([options](options: {name: string})) {
const objURL = URL.createObjectURL(blob);
const worker = new Worker(objURL, { type: "module", name: options?.name });
worker.addEventListener("error", (e) => {
URL.revokeObjectURL(objURL);
});
return worker;
}
self.MonacoEnvironment = {
getWorker: function () {
return WorkaroundWorker({ name: "mysql.worker" });
// ^^^^^^^ here's where the workaround is used
},
};
Thanks @sapphi-red! Made it work with workerpool like this:
import workerpool from 'workerpool';
import workerUrl from './worker.js?worker&url'
const js = `import ${JSON.stringify(new URL(workerUrl, import.meta.url))}`
const blob = new Blob([js], { type: "application/javascript" })
const objURL = URL.createObjectURL(blob)
const pool = workerpool.pool(objURL, { type: 'module' });
Describe the bug
I am trying to use web workers in order to not clog the main thread (when computing hashes of large files for instance).
We have a backend so I'm using some kind a backend integration in dev mode. As such, for the assets to load properly we're going the "origin" approach (i.e., forcing server.origin be https://localhost:5173 in the vite config). I won't be able to go the "proxy route" as suggested in the documentation due to network constraints.
Using this, the assets load but when using web workers, I encounter the following error:
I understand why that's the case, but I have no idea as to what I can do to make it work. I tried adding CSP headers to no avail. I know this can be circumvented by using a Blob URL and a raw import, but the code inside the worker has to be transpiled in my case since I'm doing some import there.
Everything works fine when built, I noticed it uses the "Blob trick" too, on the transpiled source.
Is there a way to mimic this in dev mode?
Reproduction
https://stackblitz.com/edit/vitejs-vite-hwpuck
Steps to reproduce
You won't able to reproduce in stackblitz but you can by downloading the code to run it locally. Open 2 terminals : one for vite and the other one for the backend. In the vite terminal, run
npm install && npm run dev
In the backend terminal, runnode server.js
Access the backend (http://localhost:8000). In the browser console, you'll see the error.System Info
Used Package Manager
yarn
Logs
No response
Validations