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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 09:07:47