feat: support node workers out of the box
Description
- Support Node workers out of the box. The current version throws an error "Worker is not defined".
- Chunk path relative to the module that calling it
Additional context
This need basepath to be unset in config if target is node
What is the purpose of this pull request?
- [ ] Bug fix
- [X] New Feature
- [x] Documentation update
- [ ] Other
Can you explain a bit about the use case of this feature?
Hi @antfu
Assume following code
// worker.js
import { parentPort } from "worker_thread"
parentPort.on("message", () => {
// some heavy work in thread
...
parentPort.postMessage("result")
}
// main.js
import MyWorker from "./worker.js?worker"
const worker = new MyWorker()
worker .postMessage("some data");
worker .on("message", result => {
// get result here
console.log(result)
}
The current "Vite" version assumes Worker class on window
Problems with Node
- Generated bundle file just cannot find a declaration for the "Worker" class and hence generate an error "Worker is not defined".
- Current version emits worker chunk by name config.base + name + postfix -> "/worker.js" ( assuming default base "/"). In generated bundle worker path will be "new Worker('/worker.js')". In the case with node, it will be resolved from the root path of the OS e.g "C:" in windows.
Solutions
- We can check if the build target is a node and add an import statement for "Worker" from "worker_thread" assuming the user will add external built-in dependencies.
- Resolve worker path relative from module who calls it using __dirname
This will let us use worker for node js without hassle.
Also, we can use typescript to define and use workers in Node.js import MyWorker from "./worker.ts?worker"
Would like to know the scenario why would you want to bundle your node app using Vite? Electron or some SSR?
@antfu I am using this for the electron app in typescript having some heavy ML work on worker threads.
I think the scenario makes sense. @prathameshnetake Can you add some tests for this PR? Thanks
@antfu Sure. I will make the test asap. Thanks
@antfu Added tests. Please have a look. Thanks
Would be great you could help documenting this feature as well
@antfu Sure I will documentation for this
Added a guide for node worker threads. Please review and provide feed back if any @Shinigami92 @antfu
@antfu Please review changes.
Is this PR dead?
I will check if the intent of this PR is already in there
Has anyone developed a good workaround for this? Trying to create a library that works both on browser and Node—but this remains a persistent challenge.
Any updates for this PR?
I'm not sure if this PR is still being considered, but I've come across a relevant use-case where the lack of support for worker_threads in Vite and Vitest is becoming a bottleneck. I'm using Vitest to test a Node package. Vitest defaults to 'node' as the environment (testTransformMode set to ssr: true). I'm facing issues when trying to work with worker_threads.
https://vitest.dev/config/#environment https://vitest.dev/config/#testtransformmode
My code, which is successfully built using SWC, fails during the testing phase in Vitest. The error message reads "Cannot find module," although the path specified is correct. Here's a simplified snippet:
import { Worker } from 'node:worker_threads'
// workerScript.ts exists in the correct location
const worker = new Worker(new URL('./workerScript.js', import.meta.url))
The lack of support for worker_threads means that Vite projects cannot use worker_threads in their SSR apps. As a side effect, it also means that Vitest users cannot test code that uses worker_threads.
As a temporary measure, I've managed to circumvent the issue by pre-compiling my code and then running the tests against the output in the dist folder, instead of directly using the src folder. While this does allow my tests to run, it undermines one of the main advantages of using Vitest, which is to streamline and simplify the testing process without requiring a separate build step.
I want to use Vite library mode to bundle a node target package with worker pool, so it means Vite still not support for now? 😂
Maybe try using the plugin directly? Just like electron-vite does
https://github.com/alex8088/electron-vite/blob/master/src/plugins/worker.ts
I think it's because Vite is primarily focused on frontend development. However, I wish Vite could support node:worker_threads, as I use Vite not only for frontend development but also for backend development with Node.js, vite-node, Fastify and vite-plugin-fastify. If it had this support, it would make working with Bree much more convenient. I could use TypeScript without having to rely on vite-plugin-static-copy to copy JavaScript files to the dist folder.
import { Worker } from 'node:worker_threads' // workerScript.ts exists in the correct location const worker = new Worker(new URL('./workerScript.js', import.meta.url))
This can be used during Vite development, but it cannot be executed properly with the build command and requires vite-plugin-static-copy to handle it. By the way, during development, Workers can also use TypeScript, but the build command cannot handle it. So, I have to write JavaScript and then copy it to the dist folder.
I think it's because Vite is primarily focused on frontend development. However, I wish Vite could support
node:worker_threads, as I use Vite not only for frontend development but also for backend development with Node.js,vite-node, Fastify andvite-plugin-fastify. If it had this support, it would make working with Bree much more convenient. I could use TypeScript without having to rely onvite-plugin-static-copyto copy JavaScript files to thedistfolder.import { Worker } from 'node:worker_threads' // workerScript.ts exists in the correct location const worker = new Worker(new URL('./workerScript.js', import.meta.url))This can be used during Vite development, but it cannot be executed properly with the
buildcommand and requiresvite-plugin-static-copyto handle it. By the way, during development, Workers can also use TypeScript, but thebuildcommand cannot handle it. So, I have to write JavaScript and then copy it to thedistfolder.
@Shyam-Chen Did you ever find a better solution to these issues? I'm just now stumbling across these as well. I'm trying to utilize vite-node for Node.js server development using TypeScript.
@Shyam-Chen Did you ever find a better solution to these issues? I'm just now stumbling across these as well. I'm trying to utilize
vite-nodefor Node.js server development using TypeScript.
@paynecodes My current solution is to use vite-plugin-static-copy to copy the JavaScript Worker file that I have written.