-
-
Notifications
You must be signed in to change notification settings - Fork 6.2k
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
fix(worker): using data URLs for inline shared worker #12014
Conversation
I'd mention that a combination of blob and shared worker does not make sense. Also, if there are valid cases when application has more than one worker, it will be not possible to have different configurations for different workers. |
docs/config/worker-options.md
Outdated
|
||
Output format for worker bundle. | ||
|
||
## worker.inlineUrl | ||
|
||
- **Type:** `'blob' | 'data'` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It better to rename by base64
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good naming, updated.
CI failed randomly, it should pass with a re-run 😅 |
@@ -287,7 +287,9 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin { | |||
export default function WorkerWrapper() { | |||
const objURL = blob && (window.URL || window.webkitURL).createObjectURL(blob); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if setting base64
is not need to createObjectURL
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated. Separate the blob and base64 code to make it more readable for human.
@pragmasoft-ua What you mentioned is correct now. Here are several solutions:
Personally, I would prefer 2. But 3 is also acceptable because it's a runtime error that throw in the browser and Vite itself does nothing wrong due to the configuration. |
Unfortunately blob shared workers do not cause runtime error. They silently work, but simply aren't shared. So, it matters to provide build error or warning, but also matters to provide valid defaults, if configuration is not provided. |
dbe765b
to
0f457a8
Compare
Update the PR. The behavior would be like this:
Additionally, the sharedworker tests're updated. The sharedworker are really dependents on multiple workers to trigger |
Thanks for the PR! But I don't think we need a config for this. Given that the blob type inline worker is just for Safari (#3468), I think we can try data-url type inline worker first and fallback to blob type inline worker. But we should not fallback to blob type worker for SharedWorker. related discussion: #8541 (comment) |
@sapphi-red Thanks for replying.
In #4674, the data-url was reintroduced for SSR compatibility. However, if we prioritize data-url as the primary option, it is uncertain whether this will cause any issues in userland. Therefore, it may be best to maintain the current behavior. Additionally, I am considering whether or not we should include blob + data fallback logic in the runtime code which could increase its size. 🤔
It's a good choice. So assuming we do not add additional config.
|
Sounds good to me 👍
Given that the fallback logic code isn't not much large, I think it's fine. |
export default function WorkerWrapper() { | ||
const objURL = blob && (window.URL || window.webkitURL).createObjectURL(blob); | ||
try { | ||
return objURL ? new ${workerConstructor}(objURL) : new ${workerConstructor}("data:application/javascript;base64," + encodedJs${workerOptions}); | ||
} finally { | ||
objURL && (window.URL || window.webkitURL).revokeObjectURL(objURL); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
try {
try {
if (!objURL) throw ''
return new ${workerConstructor}(objURL)
} catch {
return new ${workerConstructor}("data:application/javascript;base64," + encodedJs${workerOptions});
}
} finally {
objURL && (window.URL || window.webkitURL).revokeObjectURL(objURL);
}
I think we need a try-catch like this to support #12002. I haven't tested whether an error is thrown in this case though.
The current code doesn't fallback to data-uri worker when the blob worker throwed an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still could not find reproduce it but I found a similar question https://stackoverflow.com/questions/11420846/whats-wrong-with-my-code-to-record-audio-in-html5. It points to createObjectURL(stream)
throwing the error so I put that statement into the try-block.
Also, I think using one try-catch block is enough here, I made a tweak based on your suggestions. Take a look. 😀
bede82c
to
7201a46
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested with this CSP reproduction: #12002 (comment) and ensured this works. 👍
const blobCode = `${encodedJs} | ||
const blob = typeof window !== "undefined" && window.Blob && new Blob([atob(encodedJs)], { type: "text/javascript;charset=utf-8" }); | ||
export default function WorkerWrapper() { | ||
let objURL; | ||
try { | ||
objURL = blob && (window.URL || window.webkitURL).createObjectURL(blob); | ||
if (!objURL) throw '' | ||
return new ${workerConstructor}(objURL) | ||
} catch(e) { | ||
return new ${workerConstructor}("data:application/javascript;base64," + encodedJs${workerOptions}); | ||
} finally { | ||
objURL && (window.URL || window.webkitURL).revokeObjectURL(objURL); | ||
} | ||
}` | ||
|
||
const base64Code = `${encodedJs} | ||
export default function WorkerWrapper() { | ||
return new ${workerConstructor}("data:application/javascript;base64," + encodedJs${workerOptions}); | ||
} | ||
` | ||
|
||
return { | ||
// Using blob URL for SharedWorker results in multiple instances of a same worker | ||
code: workerConstructor === 'Worker' ? blobCode : base64Code, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we avoid creating the string if they aren't going to be used? Maybe directly move the template strings inside the ternary condition?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah! cleaned.
let objURL; | ||
try { | ||
objURL = blob && (window.URL || window.webkitURL).createObjectURL(blob); | ||
if (objURL) throw '' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part has been mistakenly reverted. (also the test case)
I guess you used git push --force
after the rebase. FYI there's --force-with-lease
flag that can prevent these mistakes happening.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, my bad, had cherry-picked the commits back. Thanks for the careful review. 😆
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uh, thanks @sapphi-red! Sorry, I thought it was a direct refactor. It would be good later to expand the test cases so CI would have failed on this one. Edit, ah, I see the test was also reverted, nvm.
Co-authored-by: 翠 / green <green@sapphi.red>
Description
close #11956
close #12002
Add
config.worker.inlineUrl
to select URL type from blob or dataAdditional context
What is the purpose of this pull request?
Before submitting the PR, please make sure you do the following
fixes #123
).