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

使用AdminJS向MongoDB上传图片失败的问题求助

AdminJS 图片上传配置问题排查与解决

问题背景

尝试使用AdminJS向MongoDB的StartUp模型上传Logo图片,相关代码如下:

ifile.mjs

import { mongoose } from 'mongoose';

export const ImageSchema = new mongoose.Schema({
  mime: {type: String, required: true},
});

const Image = mongoose.model("Image", ImageSchema);
export default Image;

startup.mjs

import { mongoose } from 'mongoose';

const startupSchema = new mongoose.Schema(
    {
        Logo: { type: Buffer },
        StartUp_Name:    { type: String, required: true },
        Idea_Description:{ type: String, },
    },  
    {
        timestamps: {createdAt: 'created_at', updatedAt: 'updated_at'}
    }
);

const StartUp = mongoose.model("StartUp", startupSchema);
export default StartUp;

app.mjs

// All required dependencies
import uploadFeature from '@adminjs/upload';

import StartUp from './collection/startup.mjs'
import Image, { ImageSchema } from './collection/ifile.mjs'

dotnev.config("./.env")
const PORT = process.env.PORT || 3002

const start = async () => {
const MongoStore = MongoDBStore(session);
connectDB()
const HomePage = { name: 'Home Page', icon: 'Home'}

const admin = new AdminJS({
    resources: [
    {
        resource: StartUp,
        options:
        {
        navigation: HomePage,
        bio: {
            isVisible: {
                edit: true,
                show: true,
                list: true,
                filter: true,
           },
        },
        properties: {
            // mime: { type: 'string',},
            // image: { isVisible: true, }
        },
        actions: {
        uploadFile: {
            provider:   { aws: S3 },
            validation: { mimeTypes: ['image/png', 'application/pdf'] },
            properties: { key: S3.accessKeyId, },  
        },
  
        // features:[
        //   uploadFeature({
        //     provider: { aws: S3 },
        //     validation: { mimeTypes: ['image/png', 'image/jpg', 'image/jpeg'] },
        //     properties: {
        //       key: process.env.AWS_ACCESS_KEY_SECRET
        //       mimeType: 'mimeTypes',
        //     },
        //   }),
        // ]
        },
        editProperties: ['StartUp_Name', 'Idea_Description'],
        filterProperties: ['StartUp_Name', 'Idea_Description', 'created_at'],      
        showProperties: ['StartUp_Name', 'Idea_Description'], 
        },
    ],
    rootPath: "/admin",
    },
    })
    const adminRouter = AdminJSExpress.buildRouter(admin)
    app.use(cors());
    app.use(admin.options.rootPath, adminRouter)
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));
    
    app.listen(PORT, () => {
        console.log(`AdminJS started on http://localhost:${PORT}${admin.options.rootPath}`)
})
start()

遇到的问题

  1. 使用uploadFile自定义action时,右上角上传按钮点击无实际功能;
  2. 启用注释的uploadFeature配置时,触发TypeError:
............./backend/node_modules/@adminjs/upload/build/features/upload-file/utils/bundle-component.js:7
return loader.add(componentName, componentPath);
^

TypeError: Cannot read properties of undefined (reading 'add')
at bundleComponent (............./backend/node_modules/@adminjs/upload/build/features/upload-file/utils/bundle-component.js:7:19)
at uploadFeature (............./backend/node_modules/@adminjs/upload/build/features/upload-file/upload-file.feature.js:63:31)
at uploadFileFeature (............./backend/node_modules/@adminjs/upload/build/features/upload-file/upload-file.feature.js:102:12)
at start (............./backend/app.mjs:184:17)
at ............./backend/app.mjs:446:1

Node.js v18.16.0
[nodemon] app crashed - waiting for file changes before starting...

尝试本地文件系统存储时也出现相同错误,配置如下:

features: [
    uploadFeature({
        provider: localProvider,
        validation: { mimeTypes: ['image/png', 'application/pdf'],},
        options: {
        key: 323,
        bucket: './public/files',
        s3Key: 'uploadFeature',
    },
    }),
],

解决步骤

问题1:uploadFile按钮无功能

uploadFile是自定义action,当前仅定义了元数据,未实现文件上传的核心处理逻辑,因此点击无反应。AdminJS官方推荐使用uploadFeature实现文件上传,直接放弃该自定义action方案。

问题2:uploadFeature触发TypeError的解决

1. 修正Schema字段

StartUp模型需同时存储文件的Buffer数据和MIME类型,修改startup.mjs:

const startupSchema = new mongoose.Schema(
    {
        Logo: { type: Buffer },
        Logo_mime: { type: String }, // 新增MIME类型存储字段
        StartUp_Name:    { type: String, required: true },
        Idea_Description:{ type: String, },
    },  
    {
        timestamps: {createdAt: 'created_at', updatedAt: 'updated_at'}
    }
);

2. 修正uploadFeature配置位置

之前将features数组放在actions对象内部,属于错误位置。features是resource配置的顶级属性,需与options同级。

3. 正确配置uploadFeature与依赖

首先安装必要依赖:

npm install @adminjs/express express-formidable dotenv

然后修改app.mjs核心配置:

// 修正dotenv导入与配置
import dotenv from 'dotenv';
dotenv.config({ path: './.env' });

// 导入本地存储provider(使用S3则替换为对应配置)
import { localProvider } from '@adminjs/upload';

// 修正AdminJS资源配置
const admin = new AdminJS({
    resources: [
    {
        resource: StartUp,
        // 正确放置features数组
        features: [
            uploadFeature({
                provider: localProvider,
                validation: { mimeTypes: ['image/png', 'image/jpg', 'image/jpeg'] },
                properties: {
                    key: 'Logo', // 对应Schema中的Buffer字段
                    mimeType: 'Logo_mime', // 对应新增的MIME字段
                },
                options: {
                    bucket: './public/files', // 本地存储路径,需确保目录存在且有读写权限
                    // 若使用S3,替换为以下配置:
                    // bucket: process.env.AWS_S3_BUCKET,
                    // region: process.env.AWS_REGION,
                    // accessKeyId: process.env.AWS_ACCESS_KEY_ID,
                    // secretAccessKey: process.env.AWS_ACCESS_KEY_SECRET,
                },
            }),
        ],
        options: {
            navigation: HomePage,
            // 将Logo字段加入编辑和展示属性
            editProperties: ['StartUp_Name', 'Idea_Description', 'Logo'],
            filterProperties: ['StartUp_Name', 'Idea_Description', 'created_at'],      
            showProperties: ['StartUp_Name', 'Idea_Description', 'Logo'], 
        },
    },
    ],
    rootPath: "/admin",
})

// 修正adminRouter生成,添加formidable支持
const adminRouter = AdminJSExpress.buildRouter(admin, {
    // 可选:添加认证逻辑,无需认证可返回null
    authenticate: async (email, password) => {
        if (email === process.env.ADMIN_EMAIL && password === process.env.ADMIN_PASSWORD) {
            return { email };
        }
        return null;
    },
    formidableOptions: {}, // 必须配置,用于处理文件上传
})

4. 修复其他语法错误

  • 修正dotnev为dotenv并正确导入;
  • 确保connectDB函数正确实现MongoDB连接;
  • 确保session、cors、bodyParser等依赖已正确导入。

验证

启动服务后,进入AdminJS的StartUp编辑页面,即可看到Logo字段的文件上传控件,点击后可弹出文件选择窗口完成上传。

内容的提问来源于stack exchange,提问作者Yash Maheshwari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 06:54:56