-
Notifications
You must be signed in to change notification settings - Fork 30k
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
Support web workers in webviews #87282
Comments
@mjbvz Are web workers available inside web views ? |
I don't think we can enable them at the moment. We serve up the WebViews in its own origin, this causes chrome to throw a security error:
|
This feature request is now a candidate for our backlog. The community has 60 days to upvote the issue. If it receives 20 upvotes we will move it to our backlog. If not, we will close it. To learn more about how we handle feature requests, please see our documentation. Happy Coding! |
This feature request has not yet received the 20 community upvotes it takes to make to our backlog. 10 days to go. To learn more about how we handle feature requests, please see our documentation. Happy Coding |
🙂 This feature request received a sufficient number of community upvotes and we moved it to our backlog. To learn more about how we handle feature requests, please see our documentation. Happy Coding! |
It is very likely the common usecase of this would be to embed an instance of Monaco in the webview (as seen in the original post). I know several people who want to do this as well. Wouldn't it be better for performance & usability to instead provide an API to use VSCode's native Monaco & editing tools for your custom file editor?
SW support would provide that option for other things, but it is not far off to assume that the primary use of this feature would be to get the Monaco editor. Therefore, a (presumably) more performant & usage friendly feature should be considered. |
@mjbvz should we rename this issue to support web workers in webviews? I'd like this as well, just not for monaco. |
September plan has this assigned to me #132467 which I just noticed :) @mjbvz regarding the error in #87282 (comment),
and internally we map uuid to the extension path to provide the resource via custom handler.
This is purely an issue on our end with the type of URL created and not the runtime. |
@deepak1556 I believe the url for worker scripts should now use
Trying to load this worker still fails though since the origin of the worker doesn't match the origin of the webview's iframe:
|
It can be worked around by making the CORS fetch first on the main thread and then creating a blob URL for the worker script which adheres to the same origin policy declared in the spec, here is an updated version of the frame file https://gist.github.com/deepak1556/36c31867ad3a11c3b03a56ca8bd3f536#file-frame-html Don't we already do something similar on the web ? |
Ah yes good call about blob urls! This works in the webview example extension: const workerSource = `console.log('hello worker');`
const blob = new Blob([workerSource], { type: 'application/javascript' });
const blobUrl = URL.createObjectURL(blob)
new Worker(blobUrl); So it looks like we do support workers but they effectively have to be inlined |
I guess this wouldn't support dynamic imports of the form |
@Tyriar You can using // Get the url to the worker
const workerSource = document.currentScript.getAttribute('src').replace('main.js', 'worker.js');
fetch(workerSource).then(result => result.blob()).then(blob => {
const blobUrl = URL.createObjectURL(blob)
new Worker(blobUrl);
}); |
@mjbvz I mean using dynamic imports from inside the worker, I don't think that's what you mean in your example? |
Yes that won't work: you'd need to bundle the worker into a single file The only way I can see to work around this would be updating the urls we use for loading resources from extensions to be on the same origin as the webview: On web for example, a webview will be on something like While a resource will come from something like This may be possible to do but we would need to make sure it wouldn't regress anything related to security. Also would add back a lot of complexity we were able to remove when we switched to use a static origin for webview resources |
@mjbvz can we expose the whole extension's contents on `https://59f57046-480c-462d-ae42-1caf2c4b7cb6.vscode-webview.net'? While I certainly could do this, it adds a lot of work on the extension's side to handle this and it will probably slow down webpack quite a bit as I'll have heaps of targets and extra overhead when adding more "tasks" (what I use for resize image, fill, etc.) |
Additionally all of this extra work will be VS Code specific and my server-based target which I use for tests will use a separate mechanism and I'd need to maintain both. |
Maybe, but like I said we'd have to think if this introduces any new security concerns and I really don't want to add back in the quite fragile code we needed to support resources under the same dynamic origin that the webview itself is hosted on I don't think it's worth it if we have a reasonable workaround |
Depends on your definition of reasonable as we're essentially creating a branch new vscode-specific worker API, will monaco support our new "VS Code webview-based worker API"? What about any other unaffiliated library that gets used in webviews? FWIW I don't understand what the security concerns are though. |
Yeah if we are using CORS worker then relative importScripts cannot be used, as they are resolved to the document base URL.
You would have to make them absolute urls dynamically, for ex: // From the top-level document
myWorker.postMessage({origin: workerResourceOrigin})
// In the worker file
self.onmessage = (ev) => {
if (ev.origin) {
importScripts(`${ev.origin}` + path) // Since these resolve synchronously, all these imports have to be pushed back till we know the origin to rewrite.
}
}
Yup this would be the best way forward, it is not ideal for extensions to implement above hacks to get working on the desktop client.
Did we have extension resources loaded over custom protocol before ? It would be good to understand concerns related to this switch. |
We did, and it caused a lot of headaches. When I was commenting before, I actually forgot that on desktop the webview's origin is a custom protocol: However even before switching to service workers on desktop, I believe we served the webview content that we own in a distinct origin from the webview resources that come from extensions/the workspace |
I documented how to use web workers in webviews here: https://github.com/Microsoft/vscode-docs/blob/eb58fbbf6c26e781f33aec963eeba0139337ba87/api/extension-guides/webview.md#L798 I'm closing this issue since workers do work not. If enough extension authors start running into the current limitations , we can see what we can do to relax them in the future |
I am good with above solution for now, based on #87282 (comment) it looks like we don't support workers on the web out of box because of the origin restrictions. But if we come to relax the origin policy on the web, it would be great to follow-up on the desktop as well. |
@mjbvz I'm not 100% sure but it sounds like the verification work here is to just verify the documentation? No changes were made, web workers aren't supported in webviews unless you stick everything into a single js file? |
Yes that's correct: the fix was documenting the proper approach so I'm going to mark as verified based on the docs existing |
I'm using the monaco-editor-webpack-plugin to load monaco within a
vscode
extension, but I'm running into an error around the webworkers when it loads the json language:are webworkers just not supported?
this is the code to set the
vscode-resource
in my extensionand how it gets used:
The text was updated successfully, but these errors were encountered: