Skip to content
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

[DevTools Bug]: gl.useProgram(program); will cause react-refresh to perform incorrect code injection. #31279

Open
Yukiniro opened this issue Oct 17, 2024 · 3 comments
Labels
Component: Developer Tools Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug Type: Bug

Comments

@Yukiniro
Copy link

Website or app

https://github.com/Yukiniro/reproduce/tree/master/rspack-issue-hot-update-worker

Repro steps

  1. clone https://github.com/Yukiniro/reproduce/tree/master/rspack-issue-hot-update-worker
  2. Run pnpm run dev
  3. Go to http://localhost:8080/
      const setup = () => {
        const offscreenCanvas = new OffscreenCanvas(100, 100);
        const gl = offscreenCanvas.getContext("webgl2");

        const program = gl.createProgram();
        gl.linkProgram(program);
        gl.useProgram(program);
      };
will be transform to be:
      var _s = $RefreshSig$();
      const setup = () => {
        _s();
        const offscreenCanvas = new OffscreenCanvas(100, 100);
        const gl = offscreenCanvas.getContext("webgl2");

        const program = gl.createProgram();
        gl.linkProgram(program);
        gl.useProgram(program);
      };

Then, I use the setup string to create a worker.

const worker = new Worker(URL.createObjectURL(new Blob([`(${setup})()`])));
console.log(worker);

There will throw a error in the worker becuase of _s().

I am not sure if this is a bug. If not, what could I do sometion to skip the generation of _s().

How often does this bug happen?

Every time

DevTools package (automated)

No response

DevTools version (automated)

No response

Error message (automated)

No response

Error call stack (automated)

No response

Error component stack (automated)

No response

GitHub query string (automated)

No response

@ry-krystal
Copy link

This issue arises because React's Hot Module Replacement (HMR) mechanism automatically inserts helper functions like _s(), which can cause problems when running in a Worker environment. Since the Worker environment is isolated, it cannot access the main thread's context and global variables, leading to errors.
Solutions:

  1. Disable HMR Plugin: If you don't need hot updates inside the Worker, try disabling the HMR plugin for modules related to Worker. You can modify the webpack or rspack configuration to exclude the Worker files from HMR.Like this:
    module.exports = {
    plugins: [
    new webpack.HotModuleReplacementPlugin({
    exclude: /worker.js/ // Replace with your worker file path
    }),
    ],
    };
  2. Build Worker Separately: Separate the Worker logic into an independent file and build it separately. Then, use URL.createObjectURL to load the built file. This can be achieved using worker-loader for webpack/rspack or rollup plugins for vite.
  3. Use importScripts: If you need to share scripts within the Worker, consider using importScripts to load external resources.
  4. Avoid HMR Identifiers: Try using Babel or Webpack plugins to remove HMR-related identifiers. Specifically, configure babel to ignore HMR-inserted code.

@Yukiniro
Copy link
Author

Thanks for your suggestion. And I noticed that it can use /* @refresh reset */ for some side effects, so, can we provide something like /* @refresh ignore*/ to avoid injecting code in some scenarios, such as WebGLRenderingContext.useProgram() ?

@ry-krystal
Copy link

Yes, introducing a /* @refresh ignore / directive to tell the compiler or bundler to avoid injecting code in specific cases (like critical WebGL operations) is a practical and feasible solution. This would help you mark specific functions or sections of code that should not trigger automatic refresh behavior or have code injection.
Example Usage:
/
@refresh ignore */
const setupWebGL = () => {
const program = gl.createProgram();
gl.linkProgram(program);
gl.useProgram(program); // Avoid injecting HMR code here due to potential interference.
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: Developer Tools Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug Type: Bug
Projects
None yet
Development

No branches or pull requests

2 participants