NodeJS渐进转TS:创建tsconfig后触发OverwriteModelError求助
问题
将现有NodeJS项目渐进式迁移至TypeScript,希望同时兼容JavaScript与TypeScript代码以逐步完成转换。此前项目运行正常,但创建tsconfig.json并执行npm run build构建成功后,执行npm run dev时触发错误:
OverwriteModelError: Cannot overwrite BusDayWiseBreakDown model once compiled.
目前尚未创建任何.ts文件,请问是否需要修改tsconfig.json或存在其他问题?
以下是tsconfig.json配置:
{ "compilerOptions": { "target": "es5", "module": "commonjs", "rootDir": "./src/", "moduleResolution": "node", "typeRoots": [ "./node_modules/@types", "./src/types" ], "allowJs": true, "checkJs": false, "outDir": "./built", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, "noImplicitAny": true, "skipLibCheck": true }, "include": ["./src/**/*"], "exclude": [ "node_modules", "node_modules/**/*", "./node_modules", "./node_modules/*", "./node_modules/@types/node/index.d.ts" ] }
package.json中的构建与运行命令:
- Build:
"build": "tsc -p tsconfig.json" - DEV:
"dev": "cross-env NODE_ENV=development LOGGLY_ACTIVE=false ts-node-dev --watch ./src -P tsconfig.json built/index.js"
报错相关的BusDayWiseBreakDown模型文件内容:
const mongoose = require('mongoose'); const { toJSON } = require('../../utils/mongoPlugins'); const BusDayWiseBreakDownSchema = mongoose.Schema( { busNumber: { type: String }, cityId: { type: String }, agencyId: { type: String }, afcsAccountId: { type: String }, agencyName: { type: String }, depotName: { type: String }, afcsAccountName: { type: String }, operatorEmailId: { type: String }, depotId: { type: String }, operatorId: { type: String }, operatorName: { type: String }, totalIssueCardCashAmt: { type: Number }, waybillNumber: { type: Number }, waybillStatus: { type: String }, totalRechargeCashAmt: { type: Number }, totalIssueTicketByCash: { type: Number }, totalPassIssueCashAmt: { type: Number }, totalCardCollection: { type: Number }, travelDate: { type: Number }, ticketByPrepaidCard: { type: Number }, ticketByPass: { type: Number }, etimCash: { type: Number }, driverSalary: { type: Number }, conductorSalary: { type: Number }, closureTime: { type: Date } // for running waybills it is the running time }, { timestamps: true, collection: 'BusDayWiseBreakDown', }, ); BusDayWiseBreakDownSchema.index({ busNumber: 1 }); // add plugin that converts mongoose to json BusDayWiseBreakDownSchema.plugin(toJSON); /** * @typedef BusDayWiseBreakDown */ const BusDayWiseBreakDown = mongoose.model('BusDayWiseBreakDown', BusDayWiseBreakDownSchema); module.exports = BusDayWiseBreakDown;
解决方案
问题根源
当前dev命令逻辑矛盾:先用tsc把src编译到built目录,再用ts-node-dev运行built/index.js,但ts-node-dev同时监听src目录,导致同一模型文件被加载两次——一次是built下的编译后文件,一次是src下的原文件,触发Mongoose模型重复编译错误。此外tsconfig的exclude配置冗余,也加剧了模块解析混乱。
修复步骤
- 调整dev命令
ts-node-dev可直接编译运行JS/TS文件,无需先编译到built目录。修改命令为:
"dev": "cross-env NODE_ENV=development LOGGLY_ACTIVE=false ts-node-dev --watch ./src -P tsconfig.json src/index.js"
直接运行src入口文件,避免同时加载src和built的重复代码。
- 优化tsconfig.json配置
移除冗余的exclude配置,保留必要项:
"exclude": ["node_modules"]
保持allowJs: true以兼容JS代码,确保渐进式迁移的基础配置正常。
- 模型文件兜底处理(可选)
在模型定义时先检查是否已存在,避免重复注册:
const BusDayWiseBreakDown = mongoose.models.BusDayWiseBreakDown || mongoose.model('BusDayWiseBreakDown', BusDayWiseBreakDownSchema);
内容的提问来源于stack exchange,提问作者Roomi
相关产品推荐
相关产品推荐

