NestJS中GraphQLUpload导入失败及GraphQL图片上传方案咨询
解决NestJS GraphQL图片上传的问题
一、修复graphql-upload导入错误
你遇到的Module "graphql-upload" has no exported member 'GraphQLUpload'问题,是因为graphql-upload从v16版本开始修改了导出结构:
- 旧版本(v15及以下)支持
import { GraphQLUpload } from 'graphql-upload' - v16+版本需要单独导入
GraphQLUpload模块:
// 正确导入方式 import GraphQLUpload from 'graphql-upload/GraphQLUpload.js';
二、完整NestJS GraphQL上传实现步骤
1. 确保依赖版本兼容
确认你的package.json中依赖版本匹配:
{ "dependencies": { "graphql": "^16.3.0", "graphql-upload": "^16.0.2", "@nestjs/graphql": "^10.0.0", "@nestjs/apollo": "^10.0.0", "apollo-server-express": "^4.0.0" } }
执行安装命令:
npm install
2. 添加GraphQL上传中间件
在main.ts中配置graphqlUploadExpress中间件,处理multipart/form-data请求:
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { graphqlUploadExpress } from 'graphql-upload'; async function bootstrap() { const app = await NestFactory.create(AppModule); // 添加上传中间件,设置文件大小限制(可选) app.use(graphqlUploadExpress({ maxFileSize: 10000000, maxFiles: 10 })); await app.listen(3000); } bootstrap();
3. 定义GraphQL上传类型
在你的GraphQL模块(比如app.module.ts)中注册Upload标量:
import { Module } from '@nestjs/common'; import { GraphQLModule } from '@nestjs/graphql'; import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo'; import GraphQLUpload from 'graphql-upload/GraphQLUpload.js'; import { AppResolver } from './app.resolver'; @Module({ imports: [ GraphQLModule.forRoot<ApolloDriverConfig>({ driver: ApolloDriver, autoSchemaFile: true, // 注册自定义标量 resolvers: { Upload: GraphQLUpload, }, }), ], providers: [AppResolver], }) export class AppModule {}
4. 编写上传Mutation Resolver
创建处理上传的Resolver,接收文件并处理:
import { Args, Mutation, Resolver } from '@nestjs/graphql'; import { FileUpload, GraphQLUpload } from 'graphql-upload'; import { createWriteStream } from 'fs'; import { join } from 'path'; @Resolver() export class AppResolver { @Mutation(() => String) async uploadFile( @Args({ name: 'file', type: () => GraphQLUpload }) { createReadStream, filename }: FileUpload, ): Promise<string> { return new Promise((resolve, reject) => { // 保存文件到指定目录 const filePath = join(process.cwd(), 'uploads', filename); createReadStream() .pipe(createWriteStream(filePath)) .on('finish', () => resolve(`文件上传成功:${filePath}`)) .on('error', (err) => reject(`上传失败:${err.message}`)); }); } }
三、更优替代方案:使用NestJS官方文件上传结合GraphQL
如果你觉得graphql-upload配置繁琐,可以直接用NestJS的FileInterceptor结合GraphQL的@Args接收文件:
1. 安装依赖
npm install @nestjs/platform-express multer
2. 编写Resolver
import { Args, Mutation, Resolver, UseInterceptors } from '@nestjs/graphql'; import { FileInterceptor } from '@nestjs/platform-express'; import { diskStorage } from 'multer'; import { extname } from 'path'; @Resolver() export class AppResolver { @Mutation(() => String) @UseInterceptors( FileInterceptor('file', { storage: diskStorage({ destination: './uploads', filename: (req, file, cb) => { const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9); cb(null, `${file.fieldname}-${uniqueSuffix}${extname(file.originalname)}`); }, }), }), ) async uploadFile(@Args('file') file: Express.Multer.File): Promise<string> { return `文件上传成功:${file.path}`; } }
这种方式无需额外配置GraphQL标量,直接利用NestJS的文件上传拦截器,更符合Nest的生态风格。
内容的提问来源于stack exchange,提问作者Antonymous
相关产品推荐
相关产品推荐

