vercel / next.js

The React Framework
https://nextjs.org
MIT License
127.08k stars 27.01k forks source link

Issues creating web workers `SecurityError: Failed to construct 'Worker'` #72376

Open pantoninho opened 1 week ago

pantoninho commented 1 week ago

Link to the code that reproduces this issue

https://github.com/pantoninho/nextjs-worker-bug

To Reproduce

(I'm getting errors creating a next-app with reproduction-template, so I created a regular next-app instead)

I'm able to create web workers inside a component, but a SecurityError is thrown when instantiating them inside a hook.

  1. run npm run dev
  2. open localhost:3000
  3. assert there's no issues with the created webworker by clicking send message button
  4. open localhost:3000/issue (or click the link in the root page) and a SecurityError is thrown (attached below)
  5. check the code differences between app/page.tsx and app/issue/page.tsx:
// this works
function Component() {
  const workerRef = React.useRef();

  React.useEffect(() => {
    workerRef.current = new Worker(new URL("./worker.ts", import.meta.url)); // <-- works
    return () => {
      workerRef.current?.terminate();
    };
  }, []);

  return <div />
}
// this doesn't work
function Component() {
  const worker = useWorker('./worker.ts');

  return <div/>  
}

function useWorker(path) {
  const workerRef = React.useRef();

  React.useEffect(() => {
    workerRef.current = new Worker(new URL(path, import.meta.url)); // <-- SecurityError is thrown
    return () => {
      workerRef.current?.terminate();
    };
  }, [path]);

  return workerRef;
}
image

Current vs. Expected behavior

I expected to be able to create web workers inside hooks.

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.5.0: Wed May  1 20:12:58 PDT 2024; root:xnu-10063.121.3~5/RELEASE_ARM64_T6000
  Available memory (MB): 16384
  Available CPU cores: 10
Binaries:
  Node: 20.18.0
  npm: 10.8.2
  Yarn: N/A
  pnpm: 9.12.2
Relevant Packages:
  next: 15.0.2 // Latest available version is detected (15.0.2).
  eslint-config-next: 15.0.2
  react: 19.0.0-rc-02c0e824-20241028
  react-dom: 19.0.0-rc-02c0e824-20241028
  typescript: 5.6.3
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Not sure, Runtime, Webpack

Which stage(s) are affected? (Select all that apply)

next dev (local), next build (local), next start (local)

Additional context

No response

dmsoares commented 2 days ago

I'm facing the same issue. I can confirm the repro example above is also producing the error on my machine.

EDIT: When trying to construct the URL outside the useWorker hook, a different error occurs: Refused to execute script from 'http://localhost:3000/_next/static/media/worker.de10a9a9.ts' because its MIME type ('video/mp2t') is not executable.

The page is rendered correctly, but the web worker does not seem to start (also can't find the worker script under 'sources' inside Chrome Dev Tools, as I think it should be?)

Code:

// this doesn't work
function Component() {
  const worker = useWorker(new URL("./worker.ts", import.meta.url));

  return <div/>  
}

function useWorker(url) {
  const workerRef = React.useRef();

  React.useEffect(() => {
    workerRef.current = new Worker(url); // <-- Error is thrown
    return () => {
      workerRef.current?.terminate();
    };
  }, [path]);

  return workerRef;
}