You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Render部署MERN应用时遭遇类型错误与模块未找到错误

部署MERN应用到Render时的TypeScript构建错误及解决方案

构建错误信息

../backend/src/models/hotel.ts(1,22): error TS2307: Cannot find module 'mongoose' or its corresponding type declarations.
../backend/src/models/user.ts(1,22): error TS2307: Cannot find module 'mongoose' or its corresponding type declarations.
../backend/src/models/user.ts(2,20): error TS2307: Cannot find module 'bcryptjs' or its corresponding type declarations.
../backend/src/models/user.ts(22,8): error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.
../backend/src/models/user.ts(23,9): error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.
../backend/src/models/user.ts(23,43): error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.

相关代码(user.ts)

import mongoose from "mongoose";
import bcrypt from "bcryptjs";

export type UserType = {
    _id: string;
    email: string;
    password: string;
    firstName: string;
    lastName: string;
};

const userSchema = new mongoose.Schema({
    email:{type:String,required:true,unique:true},
    password:{type:String,required:true},
    firstName:{type:String,required:true},
    lastName:{type:String,required:true}
});

//function to be executed before saving the user to the database
//this is actually a middleware
userSchema.pre("save", async function(next: mongoose.CallbackWithoutResultAndOptionalError){
    if(this.isModified("password")){
        this.password = await bcrypt.hash(this.password,10);
    }
    next();
});

const User = mongoose.model<UserType>("User",userSchema);

export default User;

已执行操作与环境信息

  • 安装类型声明:npm install --save-dev @types/mongoose @types/bcryptjs
  • tsconfig.json配置:
    {
      "compilerOptions": {
        "types": ["node"]
      }
    }
    
  • VS Code中this的类型提示正常,显示:
    this: mongoose.Document<unknown, {}, mongoose.FlatRecord<{
        firstName: string;
        lastName: string;
        email: string;
        password: string;
    }>> & mongoose.FlatRecord<{
        firstName: string;
        lastName: string;
        email: string;
        password: string;
    }> & {
        ...;
    }
    
  • 依赖版本:
    {
      "@types/mongodb": "^3.6.8",
      "@types/mongoose": "^5.11.97",
      "@types/bcryptjs": "^2.4.6",
      "bcryptjs": "^2.4.3",
      "mongodb": "^6.3.0",
      "mongoose": "^6.0.12"
    }
    
  • Render构建命令:
    cd frontend && npm install && npm run build && cd ../backend && npm run build
    

解决步骤

1. 修复类型声明与库版本不匹配问题

当前@types/mongoose是5.x版本,但实际mongoose是6.x版本,版本不兼容会导致TS无法识别模块。执行以下命令更新类型声明:

npm uninstall @types/mongoose
npm install --save-dev @types/mongoose@^6.0.0

同时更新@types/mongodb以匹配mongoose 6.x版本:

npm uninstall @types/mongodb
npm install --save-dev @types/mongodb@^4.0.0

2. 调整tsconfig.json配置

确保TypeScript能正确识别类型声明与源码目录,修改配置如下:

{
  "compilerOptions": {
    "target": "ES6",
    "module": "CommonJS",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "types": ["node", "mongoose", "bcryptjs"]
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

3. 显式指定中间件中this的类型

修改user.ts代码,为pre-save中间件的this指定明确类型:

import mongoose, { Document, CallbackWithoutResultAndOptionalError } from "mongoose";
import bcrypt from "bcryptjs";

export type UserType = {
    _id: string;
    email: string;
    password: string;
    firstName: string;
    lastName: string;
};

// 定义包含UserType的Document接口
interface UserDocument extends Document, UserType {}

const userSchema = new mongoose.Schema<UserDocument>({
    email:{type:String,required:true,unique:true},
    password:{type:String,required:true},
    firstName:{type:String,required:true},
    lastName:{type:String,required:true}
});

// 显式指定this类型为UserDocument
userSchema.pre<UserDocument>("save", async function(this: UserDocument, next: CallbackWithoutResultAndOptionalError){
    if(this.isModified("password")){
        this.password = await bcrypt.hash(this.password,10);
    }
    next();
});

const User = mongoose.model<UserDocument>("User",userSchema);

export default User;

4. 确保Render构建时安装开发依赖

Render默认生产环境会跳过devDependencies,而类型声明属于开发依赖。修改构建命令,强制安装所有依赖:

cd frontend && npm install && npm run build && cd ../backend && npm install --include=dev && npm run build

内容的提问来源于stack exchange,提问作者Noor Fatima

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 20:03:22