-
Notifications
You must be signed in to change notification settings - Fork 79
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
[feature request] Cross domain blob building fallback #36
Comments
This isn't because of CORS, but rather because sites like google.com tend to disallow all subresources using something like a Content Security Policy. The issue with CSP is that most configurations you find in the wild also block Blob and Data URL sources, so none of these solutions would work. CSP issues aside, I wonder if your use-case an inline Blob would work? It would be easy to add an option for this in input: (your source code)
compiled output:
|
@developit I tried setup you suggested but it doesn't work.
ia have next error: |
@developit Adding an |
Same here - inline mode is the one thing stopping me from moving from the seemingly unmaintained worker-loader. |
Does anyone have a solution for this? The inline flag doesn't seem to do anything, compiled code just ends up like this: var s=new Worker(e,{inline:!0}) |
For the folks commenting about Building transparent Blob/inline support is likely possible, but in the meantime I would suggest using something like this to patch Worker for your use-case: function Worker(url, opts) {
return self.Worker('data:,importScripts('+JSON.stringify(url)+')', opts);
}
new Worker("./my-worker.js", { type: "module" }); The result will be a Worker instantiated via a data URL (which will mean it has an opaque origin), where the bundled worker script is fetched via importScripts. This may help with CSP, since the request will be validated as "script-src", not "worker-src". Honestly though, most websites that ship restrictive CSP's also disable Blob, Data URL and eval() scripts. I don't think any solution that tries to "work around" this is going to help much. |
@developit I tried using the workaround you mentioned but that still couldn't bypass the error Blobs apparently bypass it successfully though, I've been using worker-loader's blobs so far and they work just fine But as some of the other comments here mention, if possible, I would rather drop the unmaintained worker-loader for this plugin so it would be amazing if the inline feature became a reality |
@alangdm try this version: function Worker(url, opts) {
var blob = new Blob(['importScripts('+JSON.stringify(url)+')'], { type: 'text/javascript' });
return self.Worker(URL.createObjectURL(blob), opts);
}
new Worker("./my-worker.js", { type: "module" }); The issue I have with the |
@developit export function Worker(url, opts) {
var blob = new Blob(["importScripts(" + JSON.stringify(url) + ")"], {
type: "text/javascript"
});
return new self.Worker(URL.createObjectURL(blob), opts);
}
new Worker("../workers/my.worker.js", {
type: "module"
}); Which threw this error in Chrome:
Doing it like this also didn't seem to be bundling the worker at all though 😢
To be honest I agree with you on this, I don't really like that kind of non-standard syntax, but Blobs seem to be the only option for use cases like mine and some of the other people who commented before me |
@developit The important steps are: (function() {
var _Worker = window.Worker;
window.Worker = function (url, opts) {
var blob = new Blob(["importScripts(" + JSON.stringify(url) + ")"], {
type: "text/javascript"
});
return new _Worker(URL.createObjectURL(blob), opts);
}
})(); And on the code actually getting bundled just use it as normally recommended: new Worker("./my-worker.js", {
type: "module"
}); (My problem on the last comment was that I was adding the fix as part of the bundled code, that didn't go well) |
I didn't make it work from the first time, so just wanted to clarify that it's not necessary to add that script directly to HTML. It's a hack where you just replace native Worker with your own implementation (with importScript that won't suffer from CORS). So it's ok to just have that in your code: const _Worker = window.Worker;
window.Worker = function (url, opts) {
const blob = new Blob(["importScripts(" + JSON.stringify(url) + ")"], {
type: "text/javascript"
});
return new _Worker(URL.createObjectURL(blob), opts);
}
// worker-plugin magic still works,
// but now you can use CORS, you can specify webpack's publicPath pointing to CDN
new Worker("./my-worker.js", {
type: "module"
});
window.Worker = _Worker // put it back to not break any other worker usage |
FWIW I'd be open to adding an option to worker-plugin that outputs the shimmed code. Better yet, an option to specify "here's how to get the Worker constructor", like: // to use Node worker_threads:
new WorkerPlugin({
workerConstructor: `require('web-worker')`
})
// to use the importScripts workaround for CORS/preload:
new WorkerPlugin({
workerConstructor: `(function(u,o){return new Worker(URL.createObjectURL(new Blob(['importScripts('+JSON.stringify(u)+')'])),o)})`
}) |
this works for me, with protocal. url =location.protocol + url; |
I tried to publish 3rd party script with webpack and
worker-plugin
.I set
output.publicPath
to "https://cdn.example.com/" in this case;But I can not exec worker because of cross domain restriction.
I know this fallback works to avoid it.
but publisher need to add CORS header to fetch. (Most CDN have CORS header)
I will fork and try it at first in my hand.
The text was updated successfully, but these errors were encountered: