GraphQL文件上传出现ReadStream.prototype.open()弃用警告如何解决?
问题原因
该DEP0135弃用警告由Node.js v15+版本触发,核心原因是apollo-server-express内置依赖的旧版graphql-upload包调用了已被官方弃用的ReadStream.prototype.open()方法。同时你现有代码的流监听逻辑存在遗漏:error事件仅打印日志没有调用reject,会出现异常场景下Promise永久挂起的问题。
解决方案
方案1:替换为新版上传实现(推荐)
关闭apollo-server内置的落后上传实现,自行引入新版graphql-upload处理逻辑:
- 安装新版依赖:
npm install graphql-upload@latest
- 修改服务端启动配置,关闭内置上传并注册新的中间件:
const { ApolloServer } = require('apollo-server-express'); const { graphqlUploadExpress } = require('graphql-upload'); const server = new ApolloServer({ typeDefs, resolvers, uploads: false, // 禁用内置上传逻辑 }); // 注册自定义上传中间件,可按需调整大小、数量限制 app.use(graphqlUploadExpress({ maxFileSize: 10 * 1024 * 1024, maxFiles: 10 }));
- 优化上传处理代码,使用Node.js官方推荐的
stream/promises.pipeline替代原生pipe,更安全且不会触发弃用警告:
import { pipeline } from 'stream/promises'; import fs from 'fs'; import { v4 as uuid } from 'uuid'; export const processUpload = async (file) => { const { createReadStream, mimetype, encoding, filename } = await file; const path = `uploads/${uuid()}${filename}`; await pipeline(createReadStream(), fs.createWriteStream(path)); return { success: true, message: 'Successfully Uploaded', mimetype, filename, encoding, location: path }; };
方案2:不调整依赖做兼容处理
如果不想修改服务端依赖配置,可以直接调整上传处理逻辑,通过异步迭代流的方式消费数据,避开弃用的open方法调用:
import fs from 'fs'; import { v4 as uuid } from 'uuid'; export const processUpload = async (file) => { const { createReadStream, mimetype, encoding, filename } = await file; const path = `uploads/${uuid()}${filename}`; const writeStream = fs.createWriteStream(path); // 异步迭代流消费数据,不触发内部open调用 for await (const chunk of createReadStream()) { writeStream.write(chunk); } writeStream.end(); return new Promise((resolve, reject) => { writeStream .on('finish', () => { resolve({ success: true, message: 'Successfully Uploaded', mimetype, filename, encoding, location: path }); }) .on('error', (err) => { console.log('Error Event Emitted', err); reject(err); }); }); };
内容的提问来源于stack exchange,提问作者M Usman Iqbal
相关产品推荐
相关产品推荐

