-
-
Notifications
You must be signed in to change notification settings - Fork 273
Inline workers does not work in Edge Legacy anymore #292
Comments
Feel free to send a fix: if (URL.revokeObjectURL) {
URL.revokeObjectURL(objectURL);
} Should be easy |
No, Edge Legacy actually supports URL.revokeObjectURL, but it does not like when the Blob URL is revoked "too quickly". |
@mpk Can you create reproducible test repo? |
@Rush It is not you problem, please provide reproducible test repo, I will help |
@evilebottnawi Sure, here you go: https://github.com/mpk/worker-loader-edge |
@mpk to be honestly I can't reproduce 😕 |
I'm having a similar issue with Chrome ( Definitely seems like a race condition because if I put a breakpoint at In light of this, the root cause appears to actually be a Chrome bug however I haven't found anything in their bug tracker. |
- Will have changes to fix the Chrome loading issue. (webpack-contrib/worker-loader#292)
I could reproduce this issue consistently on IE 11. Definitely revoking the object url immediately is issue. If I tried below code its working fine. import TestWorker from 'worker-loader?inline=no-fallback!./worker';
let tmp = URL.revokeObjectURL;
URL.revokeObjectURL = function() {};
let worker = new TestWorker();
URL.revokeObjectURL = tmp;
console.log(worker); |
Can you check |
yes its there |
Weird, it should work, no errors? Can you add |
yeah, no errors |
Looks bug in browser... |
I'm also running into this issue with inline workers in IE11. Changing the URL revocation in
|
Very very very weird, somebody can provide versions and steps to reproduce, I am not against to fix it using |
Is there any chance to merge the patch about setTimeout on above or the other plan for this issue? |
@elasim Can you provide screenshot/etc of the problem? |
In this case, the screenshot is useless. there are no exception or error throws for this. UA: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; Tablet PC 2.0; rv:11.0) like Gecko
// webpack.config.js
const path = require("path");
module.exports = ({ production }) => {
const webpackConfig = {
// Documentation: https://webpack.js.org/configuration/mode/
mode: production ? "production" : "development",
resolve: {
extensions: [".js", ".jsx", ".json"],
},
module: {
rules: [
{
test: /\-worker\.js$/,
use: {
loader: "worker-loader",
options: {
inline: "no-fallback",
},
},
},
{
test: /\.js$/,
exclude: [/node_modules/],
use: [
{
loader: "babel-loader",
options: {
presets: [
[
"@babel/preset-env",
{
targets: {
browsers: [
"chrome >= 51",
"firefox >= 51",
"ie >= 11",
"safari >= 8",
"ios >= 9",
"android >= 5",
],
},
},
],
],
plugins: [
[
"@babel/plugin-transform-runtime",
{
absoluteRuntime: false,
corejs: 3,
helpers: true,
regenerator: true,
},
],
],
},
},
],
},
{
test: /\.js$/,
enforce: "pre",
use: ["source-map-loader"],
},
],
},
entry: {
test: path.join(__dirname, "lib", "index.js"),
},
output: {
path: path.join(__dirname, "dist"),
filename: "[name].es5.js",
environment: {
arrowFunction: false,
bigIntLiteral: false,
const: true,
destructuring: false,
dynamicImport: false,
forOf: false,
module: false,
},
},
performance: {
maxEntrypointSize: 250000,
maxAssetSize: 250000,
},
devtool: production ? undefined : "source-map",
};
return webpackConfig;
}; |
hm, code is just not executed? Can you add |
Can you console log https://github.com/webpack-contrib/worker-loader/blob/master/src/runtime/inline.js#L23 |
Are you sure L23 is the place what you want to put logpoint? (Blob is supported natively, so that line wasn't executed.) /******/ (function() { // webpackBootstrap
/******/ "use strict";
/******/ // The require scope
/******/ var __webpack_require__ = {};
/******/
/************************************************************************/
/******/ /* webpack/runtime/define property getters */
/******/ !function() {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = function(exports, definition) {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ }();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ !function() {
/******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
/******/ }();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ !function() {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ }();
/******/
/************************************************************************/
var __webpack_exports__ = {};
/*!*************************************************************************************************************************************************************************************************************************************************************!*\
!*** ../../common/temp/node_modules/.pnpm/babel-loader@8.2.2/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[1].use[0]!../../common/temp/node_modules/.pnpm/source-map-loader@2.0.1/node_modules/source-map-loader/dist/cjs.js!./lib/ie-worker.js ***!
\*************************************************************************************************************************************************************************************************************************************************************/
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": function() { return __WEBPACK_DEFAULT_EXPORT__; }
/* harmony export */ });
function handleMessage(event) {
self.postMessage(event.data);
}
self.addEventListener("message", handleMessage);
var default_1 =
/** @class */
function () {
function default_1() {}
return default_1;
}();
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (default_1);
/******/ })()
; |
I want to look at blob content here https://github.com/webpack-contrib/worker-loader/blob/master/src/runtime/inline.js#L29, maybey |
It's not. BlobBuilder won't used. https://github.com/webpack-contrib/worker-loader/blob/master/src/runtime/inline.js#L14-L25 is never reached because globalScope.Blob is available. and Blob data is not broken either as you can see. |
Can you show
Also do you have CORS or other security headers? |
I've already attached. see the last line of logs.
|
What about |
https://github.com/webpack-contrib/worker-loader/blob/master/src/runtime/inline.js#L35
It works now. if (globalScope.setImmediate) {
globalScope.setImmediate(URL.revokeObjectURL, objectURL);
} else {
globalScope.setTimeout(0, URL.revokeObjectURL, objectURL);
} |
Ideally we need |
This one also works. It seems like IE/Edge wasn't implement Web Worker API properly like the other API implementations does. 😢 |
Feel free to send a fix to our runtime if it is work https://github.com/webpack-contrib/worker-loader/blob/master/src/runtime/inline.js#L35, no need tests, just add comment about version and problem |
I've found a bug for this approach. |
Can you clarify? |
Here is pseudo code to reproduce. // inline-worker.js
self.addEventListener('message', ({ data }) => {
// (IE bug) this line throw an error If objectUrl is revoked for this inline worker
const url = URL.createObjectURL(new Blob(['something']));
self.postMessage({ url });
}); // main.js
const objectUrl = URL.createObjectUrl(inlineWorkerBlob);
const worker = new Worker(objectUrl);
worker.addEventListener('message', () => {
URL.revokeObjectUrl(objectUrl);
});
setTimeout(() => {
// expect to success, actual also succeed.
worker.postMessage(1);
}, 1000);
setTimeout(() => {
// expect to success, actual is fail because of bug on IE.
// objectUrl was revoked at first callback event
worker.postMessage(2);
}, 2000); |
I don't understand... |
Okay, maybe I'll capture some video stub with example repo for your understand. |
What are you trying to achieve? I don't understand at all, here is a browser problem and that's it. We need search approach to fix it. |
Oh, sorry to keep bother you. I was completely lost. So, back to how to fix it.
// inline.js
worker = new Worker(objectUrl);
worker.objectUrl = objectUrl;
return worker
// usage.js
const worker = new InlineWorker();
worker.close();
URL.revokeObjectURL(worker.objectUrl); // revoke by author
// Inject stub if worker launched inline worker. (but we can't determine that at compile-time.)
// maybe here? https://github.com/webpack-contrib/worker-loader/blob/22275e9cb0b67bc008ea2b008542303493eede18/src/utils.js#L84
var origTerminate = worker.terminate;
worker.terminate = () => {
URL.revokeObjectURL(objectUrl);
return origTerminate.call(worker);
};
worker.addEventListener('message', ({ data }) => {
if (data === ''$specialMessageForClosing'') {
URL.revokeObjectURL(objectUrl);
}
}); var origClose = self.close;
self.close = () => {
self.postMessage('$specialMessageForClosing');
origClose.call(self);
} I think option-1 is reasonable. |
If you forget to run If you need deeply help, please create reproducible repo, provide version of browser(s) and os information. I will write to Microsoft and ask them how we can fix it. |
What about adding new option for manual revoke? Is it too complicated? |
I want to avoid new options if we can solve it on code level |
I attached reproducible link and test results. https://elasim.github.io/test/ie-inline-worker-bug
|
hm, we can add |
by the way, we probably can merge PR #316 and write caveat about this issue on document or just close that. I'll respect your decision. |
What is the problem? Do you mean CORS? |
Umm.. It was Also, It could be CORS. After some investigation, I've found the information about spec for data-uri and same-origin-policy from stackoverflow. (https://stackoverflow.com/a/23895830) |
But this problem should be same with blob too |
I agree that too. But spec and actual behavior is does. Back to solution. I want to suggest about two loader which is splited from current implementation. first is child compiler which output will be string. author can choose one of them. |
What is webpack version you are use? |
I'm using 5. |
You need this loader only for inline? Because webpack 5 support worker out of box without this loader |
Yes. This is the only loader can apply babel-loader for inline-worker as far as I know. |
Honestly because webpack v5 supports workers out of box I think we need new loader, which covert module code to blob, so you can built-in I think we need deprecate it in near future in favor |
Expected Behavior
Inline worker should execute in Edge Legacy
Actual Behavior
Inline worker does not execute in Edge Legacy
Code
How Do We Reproduce?
The code should write "Log from worker" into the console. However, it does not work in Edge Legacy browser (tested on version 18.18363). The worker is created successfully, but its contents are not executed, so nothing gets logged into the console.
I have looked at the worker-loader code and found out that the problem is in
URL.revokeObjectURL(objectURL);
line ininline.js
. When I commented out that line, Edge executed the worker contents. Wrapping the call in setTimeout with 1000ms delay worked as well, but that solution seems quite hacky.This issue is not present in worker-loader 2.0.0
The text was updated successfully, but these errors were encountered: