位置:首页 > JavaScript > NestJS中正确配置AdminJS与Mongoose适配器的方法与步骤

NestJS中正确配置AdminJS与Mongoose适配器的方法与步骤

时间:2026-08-17  |  作者:夜鞌不睡  |  阅读:0

本文详解如何在 NestJS 项目中集成 AdminJS 并正确配置 Mongoose 适配器,解决因 registerAdapter 调用位置错误导致的 Express 中间件类型异常问题,并指导将 User Schema 注册为 AdminJS 资源。

如何在 NestJS 中正确配置 AdminJS 与 Mongoose 适配器

本文详解如何在 NestJS 项目中集成 AdminJS 并正确配置 Mongoose 适配器,解决因 `registerAdapter` 调用位置错误导致的 Express 中间件类型异常问题,并指导将 User Schema 注册为 AdminJS 资源。

AdminJS 本身并不直接绑定某个框架,但它的 Mongoose 适配器(@adminjs/mongoose)有个很关键的前提:必须在 AdminJS 实例初始化之前完成全局注册,不能把它当成 Express 中间件去挂载。你现在遇到的报错 Router.use() requires a middleware function but got undefined,根子就在这里——AdminJS.default.registerAdapter(...) 被错误地塞进了 expressApp.use(...) 这条调用链里。问题在于,registerAdapter 的返回值是 void,它压根不是中间件函数,Express 自然就会直接报错。

正确做法是:先注册适配器,再创建 AdminJS 实例,最后构建并挂载路由。以下是完整、可运行的配置方案:

1. 安装必要依赖

npm install adminjs @adminjs/nestjs @adminjs/express @adminjs/mongoose
# 确保已安装 mongoose 及 NestJS Mongoose 模块
npm install @nestjs/mongoose mongoose

2. 在 main.ts 中正确初始化适配器与 AdminJS

import * as process from 'process';
import { HttpAdapterHost, NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { NestExpressApplication } from '@nestjs/platform-express';
import { json, urlencoded } from 'express';

//  关键:提前导入并注册 Mongoose 适配器(必须在 new AdminJS() 之前!)
import AdminJS from 'adminjs';
import AdminJSExpress from '@adminjs/express';
import AdminJSMongoose from '@adminjs/mongoose';

//  必须在此处注册,且仅执行一次
AdminJS.registerAdapter({
Resource: AdminJSMongoose.Resource,
Database: AdminJSMongoose.Database,
});

async function bootstrap() {
const PORT = Number(process.env.PORT) || 5000;
const app = await NestFactory.create(AppModule);

// 获取底层 Express 实例
const expressApp = app.get(HttpAdapterHost).httpAdapter;

//  创建 AdminJS 实例(此时适配器已注册,User Schema 可被自动识别)
const adminJs = new AdminJS.AdminJS({
rootPath: '/admin',
resources: [
// ? 显式注册 User 资源(推荐,确保可控)
{
resource: { model: 'User', database: 'mongodb://localhost:27017/arm-club-control' },
options: {
properties: {
name: { isVisible: { list: true, filter: true, show: true, edit: true } },
email: { isVisible: { list: true, filter: true, show: true, edit: true } },
role: { type: 'string', a vailableValues: ['user', 'admin', 'moderator'] },
},
},
},
],
// ? 认证与会话配置(保持原有逻辑)
auth: {
authenticate: async (email, password) => {
// 实现你的登录逻辑(例如查询 User 模型校验密码)
return { email, password }; // 示例占位,需替换为真实逻辑
},
cookieName: 'adminjs',
cookiePassword: 'your-secure-secret-here',
},
sessionOptions: {
resa ve: true,
sa veUninitialized: true,
secret: 'your-session-secret-here',
},
});

//  构建路由中间件(这才是真正的 Express 中间件)
const router = AdminJSExpress.buildRouter(adminJs);

//  挂载到 Express 实例(非适配器注册!)
expressApp.use(adminJs.options.rootPath, router);

// 其他应用配置...
app.setGlobalPrefix('api');
app.enableCors();
app.use(json({ limit: '50mb' }));
app.use(urlencoded({ extended: true, limit: '50mb' }));

await app.listen(PORT, '0.0.0.0');
console.log(` AdminJS running at http://localhost:${PORT}/admin`);
}
bootstrap();

3. 在 AppModule 中简化 AdminModule 配置

移除 AdminModule.createAdminAsync 中冗余的适配器注册逻辑,仅保留基础配置:

import { Module } from '@nestjs/common';
import { AdminModule } from '@adminjs/nestjs'; //  仅用于 NestJS 生命周期集成
import { MongooseModule } from '@nestjs/mongoose';
import { UserModule } from './user/user.module';

@Module({
imports: [
//  AdminModule 仅负责注入,适配器已在 main.ts 注册
AdminModule.createAdminAsync({
useFactory: () => ({
adminJsOptions: {
rootPath: '/admin',
// resources 已在 main.ts 统一管理,此处可留空或仅作基础声明
},
auth: { /* 同上,或移至 main.ts 统一配置 */ },
sessionOptions: { /* 同上 */ },
}),
}),
MongooseModule.forRoot('mongodb://localhost:27017/arm-club-control'),
UserModule,
],
})
export class AppModule {}

4. 确保 User Schema 被 Mongoose 正确识别

AdminJS 的 Mongoose 适配器会自动扫描已连接的 Mongoose Model。请确认你的 UserModule 已正确注册模型:

// user.module.ts
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { User, UserSchema } from './user.schema';

@Module({
imports: [
MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
],
// ...
})
export class UserModule {}

验证技巧:应用启动后,直接访问 http://localhost:5000/admin。如果左侧菜单里已经出现 User 这一项,而且可以正常进行增删改查,那基本就说明适配已经到位了。要是没有显示,先看看控制台有没有输出 Mongoose 的连接日志;另外还得确认 User 这个 Model 名称,和 forFeature 里注册的名称是否完全一致。默认情况下,用的就是类名 User

注意事项总结

  • AdminJS.registerAdapter() 绝不可出现在 expressApp.use() 内部;
  • 适配器注册必须在 new AdminJS() 之前,且全局仅执行一次;
  • buildRouter() 返回的是标准 Express 中间件,才可安全 use()
  • 推荐在 main.ts 中集中管理 AdminJS 实例、资源与路由,避免模块间耦合;
  • 生产环境务必替换 cookiePasswordsessionOptions.secret 为强随机密钥;
  • 若使用多数据库,resource.database 需指向对应连接 URL 或已注册的 Mongoose Connection 实例。

通过以上调整,AdminJS 将无缝对接 NestJS + Mongoose,为你提供开箱即用的数据管理后台。

免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。

相关文章

更多

精选合集

更多

大家都在玩

热门话题

大家都在看

更多