Cannot execute Classic Worker in dev mode due to imports injected by Vite
See original GitHub issueDescribe the bug
Problem
When I created and executed a classic Web Worker in dev mode, browsers will throw an error:
Uncaught SyntaxError: Cannot use import statement outside a module
Here is how I created the classic Web Worker:
const classicWorker = new Worker(new URL('./worker.js', import.meta.url));
classicWorker.addEventListener('message', ({ data }) => {
// do something
});
classicWorker.postMessage('ping');
And, here is the Web Worker file. Note that it doesn’t contain any import statements or dynamic imports:
self.addEventListener('message', () => {
self.postMessage('pong');
});
Possible Reason
In dev mode, Vite will inject a special module /@vite/env
for shimming environment variables, and it will introduce an import statement. The internal “worker” and “workerImportMetaUrl” plugin inject:
Then, the worker script will become: (for the example I mentioned above)
import '/@vite/env'
self.addEventListener('message', () => {
self.postMessage('pong');
});
Because import statements aren’t allowed in classic Web Worker, browsers threw that error.
Possible Solution
I tried using importScripts
which is available in Web Worker to import that /@vite/env
module. It works for my case, since it’s a Classic Worker, not a Module Worker.
importScripts('/@vite/env'); // It works here.
// ...
However, when running Vite’s tests, they failed. It reported:
Failed to execute 'importScripts' on 'WorkerGlobalScope': Module scripts don't support importScripts().
so I don’t have ideas about fixing this problem.
Q & A
- Q: Can I just switch to Module Worker? Vite will bundle it in build mode.
A: No, because in my real case, that snippet about creating worker (
new Worker(/* */)
) comes from a third-party library, which I’m not able to control. Also, I use Firefox, fixing this bug would be better.
Reproduction
https://stackblitz.com/edit/vitejs-vite-y9bsxv?file=main.js&terminal=dev
System Info
Browsers:
Chrome 98.0.4758.102
Firefox 97.0.1
Microsoft Edge 98.0.1108.50
Used Package Manager
pnpm
Logs
No response
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn’t already an issue that reports the same bug to avoid creating a duplicate.
- Make sure this is a Vite issue and not a framework-specific issue. For example, if it’s a Vue SFC related bug, it should likely be reported to https://github.com/vuejs/core instead.
- Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- The provided reproduction is a minimal reproducible example of the bug.
Issue Analytics
- State:
- Created 2 years ago
- Reactions:2
- Comments:6 (5 by maintainers)
Top GitHub Comments
I think we can detect the case where
{ type: 'module' }
is not provided or{ type: 'classic' }
is passed with a static string and use classic workers. As @bluwy said, there are other places where we do the same. If a dynamic expression appears, we can issue an error. Or give the user a way out of Vite processing. We currently don’t support this case anyways, no? Also, I don’t think there are a lot of use cases for a dynamic worker type in the context of a Vite appI think it would be fair to assume that
type
will always be static. Vite has certain assumptions about syntax like this, e.g. forimport.meta.glob
assert raw, andnew URL(..., import.meta.url)
🤔