A minimal Node.js test framework that discovers test files and runs each one in a dedicated worker thread.
The framework is split into two main components: the main thread that orchestrates the work, and the worker threads that execute the tests.
- Uses
jest-haste-mapto crawl the project and discover all*.test.jsfiles. - Spawns one
Workerper file, passing the file path viaworkerData.
To tell the Worker constructor which script to run, we use new URL('./worker.mjs', import.meta.url).
- How it works: This creates a full, absolute URL to
worker.mjs. It uses the location of the current module (import.meta.url) as the base and resolves the relative path (./worker.mjs) from there. - Why it's important for ESM: In modern Node.js (ES Modules), file paths are treated as
file://URLs. This is the standard way to get a file path relative to the current module, replacing the__dirnamevariable from older CommonJS modules. It differs from thepathmodule, which manipulates path strings rather than creating URL objects.
- Receives
filePathfromworkerData. - Reads the file and prints its path and content in a single atomic
console.log— guaranteeing the output is never interleaved with output from sibling workers.
A Worker Thread is a separate, parallel stream of execution. Each worker:
- Runs in Isolation: It has its own V8 engine instance, its own event loop, and its own memory.
- Prevents Blocking: It executes its script (
worker.mjs) without blocking the main thread. This is crucial for performance, as it allows the main application to remain responsive while the workers perform CPU-intensive tasks in the background. - Receives and Sends Data: It's initialized with data from the main thread via the
workerDataproperty, and sends results or data back to the main thread usingparentPort.postMessage(), which the main thread receives viaworker.on('message', ...)events.
node index.mjs
└─ Main thread
├─ jest-haste-map discovers all *.test.js files
└─ for each file → new Worker("./worker.mjs", { workerData: { filePath } })
└─ Worker thread
├─ reads workerData.filePath
├─ fs.readFileSync(filePath)
└─ single console.log(path + content) ← atomic, no interleaving
node index.mjs