NestJS中AdminJS配置Mongoose及User Schema问题排查
问题解决:AdminJS + NestJS Mongoose适配器错误及User Schema配置
错误原因分析
你遇到的 TypeError: Router.use() requires a middleware function but got a undefined 是因为:
AdminJS.registerAdapter()方法本身不返回任何值(返回undefined),但你把它作为中间件传给了expressApp.use(),导致Express路由无法识别。- 同时你混合使用了NestJS官方的
AdminModule和手动创建AdminJS实例的方式,造成了配置冲突。
修复步骤及完整配置
1. 清理main.ts的冗余代码
删除main.ts中手动创建AdminJS实例、注册适配器和挂载路由的代码,因为NestJS的AdminModule会自动处理这些逻辑。修改后的main.ts如下:
import * as process from 'process'; import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { NestExpressApplication } from '@nestjs/platform-express'; import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; import { json, urlencoded } from 'express'; (async function () { const PORT: number = Number(process.env.PORT) || 5000; const app = await NestFactory.create<NestExpressApplication>(AppModule); app.setGlobalPrefix('api'); app.enableCors(); app.use(json({ limit: '50mb' })); app.use(urlencoded({ extended: true, limit: '50mb' })); const config = new DocumentBuilder() .setTitle('ARM CLUB CONTROL') .setDescription('This app is build on NEST JS') .setVersion('0.0.1') .addTag('3aqaryan') .build(); const document = SwaggerModule.createDocument(app, config); SwaggerModule.setup('/api/docs', app, document); await app.listen(PORT, '0.0.0.0', () => { console.log(`Server is started on ${PORT} port`); }); })();
2. 正确配置AppModule(注册适配器+添加User资源)
首先确保你的UserModule已经导出了User的Mongoose模型:
// user.module.ts import { Module } from '@nestjs/common'; import { MongooseModule } from '@nestjs/mongoose'; import { User, UserSchema } from './user.schema'; import { UserService } from './user.service'; import { UserController } from './user.controller'; @Module({ imports: [MongooseModule.forFeature([{ name: User.name, schema: UserSchema }])], providers: [UserService], controllers: [UserController], exports: [MongooseModule.forFeature([{ name: User.name, schema: UserSchema }])] // 导出模型供AdminModule使用 }) export class UserModule {}
然后修改AppModule,在AdminModule中注册Mongoose适配器并添加User资源:
import { Module } from '@nestjs/common'; import { AdminModule } from '@adminjs/nestjs'; import * as AdminJS from 'adminjs'; import * as AdminJSMongoose from '@adminjs/mongoose'; import { MongooseModule } from '@nestjs/mongoose'; import { UserModule } from './user/user.module'; import { User, UserSchema } from './user/user.schema'; import { authenticate } from './auth/authenticate'; // 确保你的authenticate函数路径正确 // 先注册Mongoose适配器 AdminJS.registerAdapter({ Resource: AdminJSMongoose.Resource, Database: AdminJSMongoose.Database, }); @Module({ imports: [ AdminModule.createAdminAsync({ useFactory: () => ({ adminJsOptions: { rootPath: '/admin', // 添加User资源到AdminJS resources: [ { resource: UserSchema, options: { // 自定义AdminJS中User资源的显示配置 properties: { password: { isVisible: false }, // 隐藏密码字段 refreshToken: { isVisible: false }, // 隐藏refreshToken otp: { isVisible: false }, expiresOtpIn: { isVisible: false }, }, listProperties: ['name', 'lastname', 'email', 'role', 'activated', 'createdAt'], showProperties: ['name', 'lastname', 'username', 'email', 'role', 'activated', 'clubs', 'createdAt'], editProperties: ['name', 'lastname', 'username', 'email', 'role', 'activated', 'clubs'], }, }, ], }, auth: { authenticate, cookieName: 'adminjs', cookiePassword: 'secret', }, sessionOptions: { resave: true, saveUninitialized: true, secret: 'secret', }, }), }), MongooseModule.forRoot('mongodb://localhost:27017/arm-club-control'), UserModule, ], }) export class AppModule {}
3. 关键说明
- 适配器注册必须在
AdminModule.createAdminAsync之前执行,确保AdminJS能识别Mongoose模型。 - 在
resources数组中配置User资源时,可以通过options自定义字段的可见性、列表显示项、编辑项等,提升后台管理体验。 - 确保
UserModule导出了Mongoose模型,否则AdminModule无法访问到UserSchema。
现在启动应用,访问localhost:5000/admin就能看到User资源的管理界面,之前的错误也会消失。
内容的提问来源于stack exchange,提问作者3aQaRyAn
相关产品推荐
相关产品推荐

