Giter VIP home page Giter VIP logo

Comments (54)

lawrence-witt avatar lawrence-witt commented on September 4, 2024 2

I'm also running into this issue with inline workers in IE11. Changing the URL revocation in inline.js to the following fixes it in my use case:

setTimeout(function() { URL.revokeObjectURL(objectURL) });

from worker-loader.

Shravan-Joopally avatar Shravan-Joopally commented on September 4, 2024 1

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);

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

Feel free to send a fix:

if (URL.revokeObjectURL) {
  URL.revokeObjectURL(objectURL);
}

Should be easy

from worker-loader.

mpk avatar mpk commented on September 4, 2024

No, Edge Legacy actually supports URL.revokeObjectURL, but it does not like when the Blob URL is revoked "too quickly".

from worker-loader.

Rush avatar Rush commented on September 4, 2024

inline workers stopped working for me after upgrading to 3.x and changing inline: true to inline: 'no-fallback'

image

Investigating network shows a script with contents:

importScripts('http://localhost:4000/[object%20Module]');

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

@mpk Can you create reproducible test repo?

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

@Rush It is not you problem, please provide reproducible test repo, I will help

from worker-loader.

mpk avatar mpk commented on September 4, 2024

@evilebottnawi Sure, here you go: https://github.com/mpk/worker-loader-edge

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

@mpk to be honestly I can't reproduce 😕

from worker-loader.

KallynGowdy avatar KallynGowdy commented on September 4, 2024

I'm having a similar issue with Chrome (87.0.4280.88) and Edgium (87.0.664.55) on worker-loader v3.0.6 with webpack v5.10.0.
It is worth noting that the worker loads fine on Firefox.

Definitely seems like a race condition because if I put a breakpoint at inline.js line 31 and continue after half a second then the worker loads correctly but if I disable the breakpoint then it does not load.

In light of this, the root cause appears to actually be a Chrome bug however I haven't found anything in their bug tracker.

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

Can you check revokeObjectURL is exist?

from worker-loader.

Shravan-Joopally avatar Shravan-Joopally commented on September 4, 2024

yes its there

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

Weird, it should work, no errors? Can you add try/catch for revokeObjectURL and check again

from worker-loader.

Shravan-Joopally avatar Shravan-Joopally commented on September 4, 2024

yeah, no errors

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

Looks bug in browser...

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

Very very very weird, somebody can provide versions and steps to reproduce, I am not against to fix it using setTimeout, but I want to investigate it

from worker-loader.

elasim avatar elasim commented on September 4, 2024

Is there any chance to merge the patch about setTimeout on above or the other plan for this issue?

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

@elasim Can you provide screenshot/etc of the problem?

from worker-loader.

elasim avatar elasim commented on September 4, 2024

In this case, the screenshot is useless. there are no exception or error throws for this.
following is the information about reproduced environment.

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
WinVer 20H2.19042.928

test-project
├── @babel/[email protected]
├── @babel/[email protected]
├── @babel/[email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected]
// 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;
};

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

hm, code is just not executed? Can you add console.log('BEFORE') and ``console.log('After')` between https://github.com/webpack-contrib/worker-loader/blob/master/src/runtime/inline.js#L35 in your bundled code?

from worker-loader.

elasim avatar elasim commented on September 4, 2024

seems like worker is forked with empty script.

image
image
image

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

Can you console log https://github.com/webpack-contrib/worker-loader/blob/master/src/runtime/inline.js#L23 content and blob and show me it here?

from worker-loader.

elasim avatar elasim commented on September 4, 2024

Can you console log https://github.com/webpack-contrib/worker-loader/blob/master/src/runtime/inline.js#L23 content and blob and show me it here?

Are you sure L23 is the place what you want to put logpoint? (Blob is supported natively, so that line wasn't executed.)
btw, it is the log of content and blob

Chrome
image

IE11
image

/******/ (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/[email protected]/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[1].use[0]!../../common/temp/node_modules/.pnpm/[email protected]/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);
/******/ })()
;

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

I want to look at blob content here https://github.com/webpack-contrib/worker-loader/blob/master/src/runtime/inline.js#L29, maybey BlobBuilder or getBlob is broken

from worker-loader.

elasim avatar elasim commented on September 4, 2024

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.

image

and Blob data is not broken either as you can see.

image

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

Can you show blob value here https://github.com/webpack-contrib/worker-loader/blob/master/src/runtime/inline.js#L29, here two places for bug

  • blob generation is broken
  • URL.createObjectURL is broken with blob
  • URL.revokeObjectURL is broken without any reports

Also do you have CORS or other security headers?

from worker-loader.

elasim avatar elasim commented on September 4, 2024

I've already attached. see the last line of logs.

  • blob generation is broken: No. It's working If I commented out revokeObjectURL or give some delay using setTimeout.
  • CORS or Security Header: No. this script served via webpack-dev-server. there are no such a security header.
  • URL.createObjectURL is broken with blob: No. As you can see the last image, We can read blob data via xhr and there are no error.
  • URL.revokeObjectURL is broken without any reports: Maybe. but no way to figure out.

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

What about setImmediate? Can you try? Maybe we can check setImmediate is defined and use logic, so for good browser we will keep original logic

from worker-loader.

elasim avatar elasim commented on September 4, 2024

https://github.com/webpack-contrib/worker-loader/blob/master/src/runtime/inline.js#L35

Replacing that line with globalScope.setImmediate(URL.revokeObjectURL, objectURL); works.

oops, no. Above approach throws an error on safari. I'll try another way.

It works now.

if (globalScope.setImmediate) {
  globalScope.setImmediate(URL.revokeObjectURL, objectURL);
} else {
  globalScope.setTimeout(0, URL.revokeObjectURL, objectURL);
}

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

Ideally we need if (globalScope.setImmediate) { globalScope.setImmediate(() => { URL.revokeObjectURL(objectURL) }); } else { URL.revokeObjectURL(objectURL); }

from worker-loader.

elasim avatar elasim commented on September 4, 2024

Ideally we need if (globalScope.setImmediate) { globalScope.setImmediate(() => { URL.revokeObjectURL(objectURL) }); } else { URL.revokeObjectURL(objectURL); }

This one also works.

It seems like IE/Edge wasn't implement Web Worker API properly like the other API implementations does. 😢

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

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

from worker-loader.

elasim avatar elasim commented on September 4, 2024

if (globalScope.setImmediate) { globalScope.setImmediate(() => { URL.revokeObjectURL(objectURL) }); } else { URL.revokeObjectURL(objectURL); }

I've found a bug for this approach.
After blob url is revoked, Invoking URL.createObjectURL from IE11 worker context throws an error.
Perhaps we should have to leave object url without revoking or revoke that when the worker terminated.

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

Can you clarify?

from worker-loader.

elasim avatar elasim commented on September 4, 2024

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);

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

I don't understand...

from worker-loader.

elasim avatar elasim commented on September 4, 2024

Okay, maybe I'll capture some video stub with example repo for your understand.

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

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.

from worker-loader.

elasim avatar elasim commented on September 4, 2024

Oh, sorry to keep bother you. I was completely lost.
I was telling you what's the issue is.

So, back to how to fix it.
Maybe we got 2 options.

  1. Give up self-closing and delegate revoking to the author who people using 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
  1. Putting some codes to revoke when it closed. perhaps we need some special message for this and it will need to change original behavior. like following stub.
    (I know it's messy. but I want to review all the option we can try)
// 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.

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

If you forget to run URL.revokeObjectURL, you will have memory leak, If this problem is so complex I would rather say that we do not support workers in Edge Legacy browsers due bug in browsers and you can write workaround on application side.

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.

from worker-loader.

elasim avatar elasim commented on September 4, 2024

What about adding new option for manual revoke? Is it too complicated?
I'll post reproducible repo anyway.

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

I want to avoid new options if we can solve it on code level

from worker-loader.

elasim avatar elasim commented on September 4, 2024

I attached reproducible link and test results.
Also, I'm not used webpack or worker-loader on this testbed intentionally to make it sure the issue is coming from URL.revokeObjectURL.

https://elasim.github.io/test/ie-inline-worker-bug

image

Browser version Result
Win7 IE 11 X
Win11 IE 11 X
Edge 15 X
Edge 16 X
Edge 17 X
Edge 18 X
Edge 80 O

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

hm, we can add window.navigator.msSaveOrOpenBlob check and if it is true we should always run https://github.com/webpack-contrib/worker-loader/blob/master/src/runtime/inline.js#L39

from worker-loader.

elasim avatar elasim commented on September 4, 2024
  • there are security error with using data-uri.
  • temporal URL.revokeObjectURL patching isn't useful with core-js is used.
  • app side workaround isn't acceptable with some use-case because of heavy workload.

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.

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

there are security error with using data-uri.

What is the problem? Do you mean CORS?

from worker-loader.

elasim avatar elasim commented on September 4, 2024

What is the problem? Do you mean CORS?

Umm.. It was script5022: securityerror. and seems like a restriction rather than CORS.
https://docs.microsoft.com/en-us/previous-versions//cc848897(v=vs.85)?redirectedfrom=MSDN

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)
It said same-origin-policy was changed for data-uri and that wasn't applied to data-uri before.

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

But this problem should be same with blob too

from worker-loader.

elasim avatar elasim commented on September 4, 2024

I agree that too. But spec and actual behavior is does.
(IE is annoying and frustrating always 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.
second is code injector which are depend first one and output will be same as current implements

author can choose one of them.
and if you don't want to make any breaking changes,
Perhaps I need to make fork version of this. (Only if you and CLA agree with this)

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

What is webpack version you are use?

from worker-loader.

elasim avatar elasim commented on September 4, 2024

I'm using 5.

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

You need this loader only for inline? Because webpack 5 support worker out of box without this loader

from worker-loader.

elasim avatar elasim commented on September 4, 2024

Yes. This is the only loader can apply babel-loader for inline-worker as far as I know.
By the way, I'm afraid bothering you because of this. If you are busy or it's annoying you, I'll handle this issue own myself.

from worker-loader.

alexander-akait avatar alexander-akait commented on September 4, 2024

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 new Worker('./file.js', import.meta.url) feature without this loader.

I think we need deprecate it in near future in favor new Worker('./file.js', import.meta.url), more abilities, more options, better support.

from worker-loader.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.