当第一个参数是变量时,使用“new URL()”创建相对 URL 的行为会有所不同。为什么?

IT技术 reactjs url next.js web-worker
2021-05-14 00:44:21

我正在尝试在 NextJs 中实现网络工作者,我已经遵循了他们的例子,但它真的让我感到困扰,我无法将工作者相对 URL 作为变量传递给new URL(url, baseUrl).

以下代码段是调用 worker 的地方:

import { useEffect, useRef, useCallback } from 'react'

export default function Index() {
  const workerRef = useRef()
  useEffect(() => {
    const workerUrl = '../worker.js';

    console.log({
      URL: new URL('../worker.js', import.meta.url),
      meta: import.meta.url
    });
    console.log({
      URL: new URL(workerUrl, import.meta.url),
      meta: import.meta.url
    });

    workerRef.current = new Worker(new URL('../worker.js', import.meta.url))
    workerRef.current.onmessage = (evt) =>
      alert(`WebWorker Response => ${evt.data}`)
    return () => {
      workerRef.current.terminate()
    }
  }, [])

  const handleWork = useCallback(async () => {
    workerRef.current.postMessage(100000)
  }, [])

  return (
    <div>
      <p>Do work in a WebWorker!</p>
      <button onClick={handleWork}>Calculate PI</button>
    </div>
  )
}

这奇怪地记录:

{
  "URL":"/_next/static/media/worker.3c527896.js",
  "meta":"file:///home/omar/CODE/NextJs/lullo/with-web-worker-app/pages/index.js"
}
    
{
  "URL":"file:///home/omar/CODE/NextJs/lullo/with-web-worker-app/worker.js",
  "meta":"file:///home/omar/CODE/NextJs/lullo/with-web-worker-app/pages/index.js"
}

这到底有什么不同:

    const workerUrl = '../worker.js';

    console.log({
      URL: new URL('../worker.js', import.meta.url),
      meta: import.meta.url
    });
    console.log({
      URL: new URL(workerUrl, import.meta.url),
      meta: import.meta.url
    });

问题是我无法将 URL 作为props传递给一些通用的工人调用者。我收到烦人的错误:

SecurityError: Failed to construct 'Worker': Script at 'file:///home/omar/CODE/NextJs/lullo/client/src/utils/WebWorkers/postErrorToServer.ts' cannot be accessed from origin 'http://localhost:3000'.
1个回答

这可能会发生,因为在第一种情况下:

const workerUrl = '../worker.js';
const url = new URL(workerUrl, import.meta.url);

webpack 将 URL 视为动态的,并且无法在编译时正确捆绑 web worker。如果您按如下方式定义工作人员,则会发生类似的情况:

const url = new URL('../worker.js', import.meta.url);
const worker = new Worker(url);

对 webpack 的 GitHub 存储库中的讨论的此评论可能对您的情况有所帮助。由于上述原因,我不认为工作 URL 可以是真正动态的 - webpack 需要在编译时知道工作脚本的 URL。