Heroku部署TypeScript后端遇import语法错误,求解决方案
问题:TypeScript Node.js后端部署Heroku时的import及文件扩展名异常
我用TypeScript开发的Node.js后端,本地和队友本地运行都正常,但部署到Heroku时失败。日志先是报错SyntaxError: Cannot use import statement outside a module,按照StackOverflow建议给package.json添加"type": "module"后,又出现TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts"错误。尝试多种方法无效,想咨询是否可以修改Heroku设置适配本地环境,或者有没有更优的TypeScript环境下import问题的解决方法。
当前配置
package.json
{ "name": "booknbucks-backend", "version": "1.22.15", "main": "index.js", "license": "MIT", "scripts": { "start": "node app.ts", "dev": "nodemon app.ts", "build": "tsc", "production": "node dist/app.js" }, "dependencies": { "@types/dotenv": "^8.2.0", "@types/express": "^4.17.13", "@types/mongodb": "^4.0.7", "bcryptjs": "^2.4.3", "compression": "^1.7.4", "cors": "^2.8.5", "dotenv": "^16.0.0", "express": "^4.17.2", "firebase-admin": "^10.0.2", "helmet": "^5.0.2", "jsonwebtoken": "^8.5.1", "moment": "^2.29.1", "mongoose": "^6.2.0", "mongoose-paginate-v2": "^1.6.3", "node-cron": "^3.0.0", "typescript": "^4.6.3" } }
tsconfig.json
{ "compilerOptions": { "module": "commonjs", "target": "esnext", "sourceMap": true, "esModuleInterop": true, "resolveJsonModule": true, "outDir": "dist", "baseUrl": "." }, "exclude": ["node_modules"], "include": ["**/*.ts"] }
解决方案
核心问题分析
你的部署流程跳过了TypeScript编译步骤,直接用Node运行.ts文件,同时模块系统配置冲突:
- tsconfig中指定
module: commonjs,但添加"type": "module"后Node会强制使用ES模块,两者不兼容 - Node本身不支持直接运行.ts文件,本地能跑是因为nodemon可能集成了ts-node(本地环境有依赖),但Heroku默认没有该环境
具体修复步骤
- 调整package.json配置
- 移除
"type": "module",保持模块系统与tsconfig的commonjs一致 - 修改
main字段为dist/app.js,对应编译后的入口文件 - 补充
devDependencies,添加ts-node和nodemon(本地可能全局安装,但Heroku需要明确依赖) - 新增
heroku-postbuild脚本,让Heroku部署时自动执行TypeScript编译 - 调整
start脚本,直接调用生产环境运行命令
- 移除
修改后的package.json示例:
{ "name": "booknbucks-backend", "version": "1.22.15", "main": "dist/app.js", "license": "MIT", "scripts": { "start": "npm run production", "dev": "nodemon app.ts", "build": "tsc", "production": "node dist/app.js", "heroku-postbuild": "npm run build" }, "dependencies": { "@types/dotenv": "^8.2.0", "@types/express": "^4.17.13", "@types/mongodb": "^4.0.7", "bcryptjs": "^2.4.3", "compression": "^1.7.4", "cors": "^2.8.5", "dotenv": "^16.0.0", "express": "^4.17.2", "firebase-admin": "^10.0.2", "helmet": "^5.0.2", "jsonwebtoken": "^8.5.1", "moment": "^2.29.1", "mongoose": "^6.2.0", "mongoose-paginate-v2": "^1.6.3", "node-cron": "^3.0.0", "typescript": "^4.6.3" }, "devDependencies": { "nodemon": "^2.0.15", "ts-node": "^10.7.0" } }
确认tsconfig.json配置
- 保持现有
module: commonjs和outDir: "dist"不变,确保编译产物为Node支持的CommonJS模块,且输出到dist目录
- 保持现有
Heroku部署逻辑说明
- Heroku会自动执行
npm install安装所有依赖(包括开发依赖) - 执行
heroku-postbuild脚本,运行tsc编译TypeScript代码到dist目录 - 最后执行
npm start,运行编译后的dist/app.js
- Heroku会自动执行
不需要修改Heroku全局设置,按上述步骤调整项目配置即可解决问题。
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

