threads.js icon indicating copy to clipboard operation
threads.js copied to clipboard

Avoid use of `eval` in worker_threads.ts?

Open manzt opened this issue 4 years ago • 4 comments

https://github.com/andywer/threads.js/blob/42b1042f9a0057fd25c94807ba4ac988e6475916/src/worker_threads.ts#L20

Thanks for all your work on threads.js! I am working with rollup and running into an issue due to the use of eval("require")("worker_threads") when creating an ESM output. Rollup cannot convert the eval("require") to a top-level import statement import require$$0 from 'worker_threads' since it doesn't not recognize it statically as a commonjs require("worker_threads").

This means that in the final ESM bundle ends up with a eval("require") which throws at runtime since require is not allowed when using ESM in node. I see the comment "Webpack hack" and am curious if the use of eval is a part of that hack? Or would there be an option to avoid the use of eval and change this to require("worker_threads")? Cheers!

manzt avatar Jun 22 '21 17:06 manzt

This only seemed to be an issue when I tried to generate a single bundle for the corresponding worker. However, marking threads/worker as external works just fine. It seems the runtime check in threads is suffcient (or nodes module resolution) works to allow threads/worker to be imported in a worker regardless of CJS/ESM importer.

manzt avatar Jun 22 '21 19:06 manzt

@manzt The external fix sounds plausible. Nice to see that you were able to fix it already! Yes, the eval() call is part of the webpack hack 😅

Would you mind maybe opening a PR to add some hint to the docs on how to tackle this issue? We could also open a new issue to collect ideas for a FAQ page or so.

andywer avatar Jun 23 '21 07:06 andywer

@manzt The packaged product cannot run. How did you solve this problem

r3x5ur avatar Mar 18 '23 06:03 r3x5ur

My Test Code

// main.js
async function main() {
  const thread = await spawn(new Worker('./testWork'))
  console.log(await thread())
  await Thread.terminate(thread)
}
main().catch(console.error)
// testWork.js
expose(function () {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('done')
    }, 2000)
  })
})

r3x5ur avatar Mar 18 '23 06:03 r3x5ur