如何在Heroku Scheduler中运行TypeScript文件?解决执行报错问题
我在Heroku上部署了TypeScript服务器,服务器本身运行正常,但通过Heroku Scheduler设置的每小时定时任务始终执行失败。使用的执行命令为:npx ts-node src/scheduler/weatherAlertCheck.ts
遇到的错误
- 测试执行时终端提示:
Need to install the following packages: ts-node@10.9.1 Ok to proceed? (y)
- 后续触发类型声明相关编译错误:
/app/.npm/_npx/1bf7c3c15bf47d04/node_modules/ts-node/src/index.ts:859 return new TSError(diagnosticText, diagnosticCodes, diagnostics); ^ TSError: ⨯ Unable to compile TypeScript: src/controllers/notifications.ts:3:35 - error TS7016: Could not find a declaration file for module 'express'. '/app/node_modules/express/index.js' implicitly has an 'any' type. Try `npm i --save-dev @types/express` if it exists or add a new declaration (.d.ts) file containing `declare module 'express';` 3 import { Request, Response } from "express"; ~~~~~~~~~
我的package.json配置
{ "devDependencies": { "@types/express": "^4.17.17", "@types/jsonwebtoken": "^9.0.1", "@types/node": "^18.14.0", "nodemon": "^2.0.20", "ts-node": "^10.9.1", "typescript": "^4.9.4" }, "scripts": { "dev": "npx nodemon", "build": "tsc", "postinstall": "npm run build", "start": "node build/main.js" }, "dependencies": { "@parse/node-apn": "^5.1.0", "@types/jsonwebtoken": "^9.0.1", "axios": "^1.2.6", "body-parser": "^1.20.1", "dotenv": "^16.0.3", "express": "^4.18.2", "fs": "^0.0.1-security", "jsonwebtoken": "^8.5.1", "knex": "^2.4.0", "pg": "^8.8.0", "ts-node": "^10.9.1", "typescript": "^4.9.4" } }
问题原因与解决办法
核心原因
Heroku生产环境默认不会安装devDependencies,而@types/express被归类在开发依赖中。直接用ts-node运行TypeScript源码时,需要读取类型声明文件,缺失就会触发编译失败;同时npx会尝试临时安装ts-node,进一步加剧了环境不一致问题。
最优解决步骤
改用编译后的JS文件执行定时任务
你的postinstall脚本已经配置了自动执行npm run build,会将TypeScript代码编译为JS文件输出到build目录。只需将调度器的执行命令修改为:node build/scheduler/weatherAlertCheck.js
此方案无需依赖任何开发环境包,直接运行编译产物,既高效又能避免类型声明缺失问题。确认TypeScript编译范围
检查tsconfig.json的include字段,确保包含scheduler目录,示例配置:{ "include": ["src/**/*"] }这样编译时才会将
src/scheduler下的文件也转换为JS并输出到build目录。
备选方案(不推荐)
如果坚持要用ts-node直接运行源码,需将@types/express移至dependencies(执行npm install @types/express --save),同时将调度命令改为ts-node src/scheduler/weatherAlertCheck.ts(去掉npx,因为ts-node已在生产依赖中)。但此方案会将开发依赖打包到生产环境,增加部署体积,不如直接运行编译后的JS文件合理。
内容的提问来源于stack exchange,提问作者Tim Isenman

