I want to have my worker thread as an external file from the runtime file.
My current folder structure is
src/
> service.ts // my 'main'
> thread/
>> test.js
inside my service.ts i have the following boilerplate code
import { Worker, isMainThread } from "worker_threads"
if (isMainThread) {
const testworker = new Worker('./thread/test.js')
testworker.on('error', err => console.error({ err }))
testworker.on('message', msg => console.log({ msg }))
testworker.on('exit', code => code === 0 ? console.log({ code }) : console.error({ code }))
}
inside my thread/test.js i have the following boilerplate code
import { isMainThread, parentPort } from "worker_threads"
console.log({ isMainThread, parentPort })
parentPort.postMessage("RealCookie")
When I attempt to do this, i receive the following error:
Error: Cannot find module '/srv/FOLDERNAME/thread/test.js'
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
at Function.Module._load (node:internal/modules/cjs/loader:778:27)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
at MessagePort.<anonymous> (node:internal/main/worker_thread:191:24)
at MessagePort.[nodejs.internal.kHybridDispatch] (node:internal/event_target:643:20)
at MessagePort.exports.emitMessage (node:internal/per_context/messageport:23:28) {
code: 'MODULE_NOT_FOUND',
requireStack: []
}
IF i however try to run const testworker = new Worker(__filename) then it happily run the code without issues. I do not really understand why?
--node: v17.9.1
--npm: 8.11.0
--tsconfig.json
{
"extends": "@tsconfig/node16/tsconfig.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "dist",
"noImplicitAny": true,
"lib": [
"es2021"
],
"module": "Node16",
"target": "es2021",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node"
}
}
--packages
{
"name": "hidden",
"version": "1.0.0",
"main": "dist/service.js",
"license": "MIT",
"private": true,
"devDependencies": {
"@types/express": "^4.17.17",
"@types/node": "^20.4.2",
"@types/node-cron": "^3.0.8",
"ts-node": "^10.9.1",
"ts-node-dev": "^2.0.0",
"typescript": "^5.1.6"
},
"dependencies": {
"@prisma/client": "^5.0",
"@tsconfig/node16": "^16.1.0",
"axios": "^1.4.0",
"core-util-is": "^1.0.3",
"dotenv": "^16.3.1",
"express": "^4.18.2",
"node-cron": "^3.0.2",
"prisma": "^5.0.0",
"ulid": "^2.3.0"
},
"scripts": {
"prod": "node dist/service.js",
"dev": "tsnd --clear src/service",
"build": "tsc"
}
}
I really hope this is something simply that I am missing, but at the same time I don't, because I do not want to waste anyones time. Hope someone can see what I am doing wrong here!
Your
tsconfig.jsonspecifies the build output folder as different from the source:Therefore once you build your project with
tsc, your TS files are transpiled into JS files, which are placed into thatdistfolder. Which you properly take into account in your start script:...but your
thread/test.jsfile is not copied into thatdistfolder!Even though you mention its path for the
new Worker,tscdoes not look it up, and does not handle it at all.Hence
dist/service.jsis unable to spawn a Worker using the relative./thread/test.jspath.Simply make sure that after build, that path is still correct / non built file are copied over, to reproduce your source file structure. For example you could do something in the lines of: