VPS上同时启动两个脚本时ts-node报Cannot find module './index.ts'错误
问题:Shell脚本启动ts-node进程时,多进程场景下出现模块找不到错误
我在VPS上用Shell脚本管理两个Node.js脚本的启动,脚本逻辑是检测指定进程是否运行,未运行则用ts-node启动对应的index.ts。单独启动其中一个脚本一切正常,但当一个脚本运行时启动另一个,会出现Cannot find module './index.ts'错误。
管理脚本代码
#!/bin/sh PROCESS_NAME_REGEX="process_name" TS_NODE_EXECUTABLE="./node_modules/.bin/ts-node" if ps -ef | grep -v grep | grep -qE "$PROCESS_NAME_REGEX" ; then exit 0 else $TS_NODE_EXECUTABLE /path/src/index.ts >> ./parser.log & exit 0 fi
报错信息
auto$ cd /path/ && ./always_run.sh node:internal/modules/cjs/loader:1080 throw err; ^ Error: Cannot find module './index.ts' Require stack: - /path/src/imaginaryUncacheableRequireResolveScript at Module._resolveFilename (node:internal/modules/cjs/loader:1077:15) at Function.resolve (node:internal/modules/cjs/helpers:127:19) at requireResolveNonCached (/var/path/node_modules/ts-node/dist/bin.js:549:16) at getProjectSearchDir (/var/path/node_modules/ts-node/dist/bin.js:519:40) at phase3 (/var/www/auto/data/path/node_modules/ts-node/dist/bin.js:267:27) at bootstrap (/var/path/node_modules/ts-node/dist/bin.js:47:30) at main (/var/www/auto/data/path/node_modules/ts-node/dist/bin.js:33:12) at Object.<anonymous> (/var/path/node_modules/ts-node/dist/bin.js:579:5) at Module._compile (node:internal/modules/cjs/loader:1256:14) at Module._extensions..js (node:internal/modules/cjs/loader:1310:10) { code: 'MODULE_NOT_FOUND', requireStack: [ '/path/src/imaginaryUncacheableRequireResolveScript' ] } Node.js v18.17.1
原因分析
核心问题是工作目录不一致或ts-node的项目目录缓存冲突:
- 相对路径的ts-node执行文件、日志文件,在多进程场景下可能因为工作目录变化导致路径解析错误;
- 第一个进程启动后,ts-node缓存了项目根目录信息,第二个进程启动时复用缓存,导致找不到目标模块。
解决办法
1. 强制固定工作目录
修改脚本,启动ts-node前先切换到项目根目录,确保所有路径解析一致:
#!/bin/sh PROCESS_NAME_REGEX="process_name" # 改用绝对路径指向ts-node,避免相对路径歧义 TS_NODE_EXECUTABLE="/path/node_modules/.bin/ts-node" # 明确项目根目录路径 PROJECT_ROOT="/path" if ps -ef | grep -v grep | grep -qE "$PROCESS_NAME_REGEX" ; then exit 0 else # 切换到项目根目录后执行启动命令 cd "$PROJECT_ROOT" && $TS_NODE_EXECUTABLE src/index.ts >> parser.log & exit 0 fi
2. 指定ts-node项目配置,避免缓存冲突
启动ts-node时加上--project参数,明确指定tsconfig.json路径,强制每个进程使用独立的项目配置:
cd "$PROJECT_ROOT" && $TS_NODE_EXECUTABLE --project ./tsconfig.json src/index.ts >> parser.log &
3. 优化进程检测逻辑(可选)
原有的ps -ef | grep容易出现误判,可改用PID文件实现更精准的进程检测:
#!/bin/sh PROCESS_NAME_REGEX="process_name" TS_NODE_EXECUTABLE="/path/node_modules/.bin/ts-node" PROJECT_ROOT="/path" PID_FILE="$PROJECT_ROOT/process.pid" # 检测PID文件对应的进程是否存活 if [ -f "$PID_FILE" ] && kill -0 $(cat "$PID_FILE") 2>/dev/null; then exit 0 else cd "$PROJECT_ROOT" && $TS_NODE_EXECUTABLE src/index.ts >> parser.log & # 记录当前进程PID到文件 echo $! > "$PID_FILE" exit 0 fi
内容的提问来源于stack exchange,提问作者Dmitry Larin
相关产品推荐
相关产品推荐

