createReadStream() throwing RangeError: Maximum call stack size exceeded when uploading file
createReadStream() throwing RangeError: Maximum call stack size exceeded when uploading file
我正在尝试使用 Apollo Server 的 Upload
标量直接将文件发送到 S3。我的架构:
const { gql } = require('apollo-server-express')
module.exports = gql`
extend type Mutation {
createPicture(
name: String!
picture: Upload!
): Picture!
}
type Picture {
name: String!
picture: String!
}
`
解析器:
const { combineResolvers } = require('graphql-resolvers')
const isAuthenticated = require('./auth')
const { uploadPhoto } = require('../services/picture')
module.exports = {
Mutation: {
createPicture: combineResolvers(
isAuthenticated,
async (
parent,
{ name, picture = null },
{ models, me }
) => {
const { createReadStream, filename, mimetype, encoding } = await picture
// Does not get past this line
const stream = createReadStream()
uploadPhoto(stream, filename)
const pictureModel = models.Picture.create({
name,
picture
})
return pictureModel
}
)
}
}
但是我的代码错误是这样的:
internal/util.js:55
function deprecated(...args) {
^
RangeError: Maximum call stack size exceeded
at ReadStream.deprecated [as open] (internal/util.js:55:22)
at ReadStream.open ([truncated]/node_modules/fs-capacitor/lib/index.js:90:11)
at _openReadFs (internal/fs/streams.js:123:12)
at ReadStream.<anonymous> (internal/fs/streams.js:116:3)
at ReadStream.deprecated [as open] (internal/util.js:70:15)
at ReadStream.open ([truncated]/node_modules/fs-capacitor/lib/index.js:90:11)
at _openReadFs (internal/fs/streams.js:123:12)
at ReadStream.<anonymous> (internal/fs/streams.js:116:3)
at ReadStream.deprecated [as open] (internal/util.js:70:15)
at ReadStream.open ([truncated]/node_modules/fs-capacitor/lib/index.js:90:11)
at _openReadFs (internal/fs/streams.js:123:12)
at ReadStream.<anonymous> (internal/fs/streams.js:116:3)
at ReadStream.deprecated [as open] (internal/util.js:70:15)
at ReadStream.open ([truncated]/node_modules/fs-capacitor/lib/index.js:90:11)
at _openReadFs (internal/fs/streams.js:123:12)
at ReadStream.<anonymous> (internal/fs/streams.js:116:3)
at ReadStream.deprecated [as open] (internal/util.js:70:15)
at ReadStream.open ([truncated]/node_modules/fs-capacitor/lib/index.js:90:11)
at _openReadFs (internal/fs/streams.js:123:12)
at ReadStream.<anonymous> (internal/fs/streams.js:116:3)
at ReadStream.deprecated [as open] (internal/util.js:70:15)
at ReadStream.open ([truncated]/node_modules/fs-capacitor/lib/index.js:90:11)
注意:我确信图像发送正确,因为 filename
是正确的
原来这是 this graphql-upload
中的错误。降级到节点 12 并已修复(此处列出的解决方案对我没有帮助)
我在节点版本 14 中也出现了这个错误!
我是这样解决的:
安装最新版本的 graphql-upload!
使用 graphqlUploadExpress 中间件定义最大文件限制。
import { graphqlUploadExpress } from "graphql-upload";
const app = express()
app.use(graphqlUploadExpress({ maxFileSize: 1000000000, maxFiles: 10 }));
在初始化 ApolloServer 时将上传设置为 false
const server = new ApolloServer({
uploads: false,
schema,
});
将此添加到 package.json:
"resolutions": {
"**/**/fs-capacitor":"^6.2.0",
"**/graphql-upload": "^11.0.0"
}
来源:https://github.com/jaydenseric/graphql-upload/issues/170#issuecomment-641938198
使用:
"apollo-server": "^2.18.2",
"apollo-server-express": "2.18.2",
"aws-sdk": "^2.771.0",
"express-fileupload": "^1.2.0",
"graphql": "^15.3.0",
"graphql-upload": "^11.0.0",
"fs-capacitor": "^6.2.0",
我通过安装最新的 fs-capacitor
作为依赖来解决这个问题
yarn add fs-capacitor
将此添加到您的 package.json
"resolutions": {
"graphql-upload": "^11.0.0"
}
然后在脚本中添加这个
"scripts": {
....
"preinstall": "npx npm-force-resolutions", //This one
....
}
然后你需要执行 npm install。完成
我已经多次处理这个问题
问题是旧的 graphql-upload 版本 8 更准确地使用节点打开流功能,该功能已弃用,在 13.x 和更旧的节点版本中不再可用。
所以解决方案是您可以使用 nvm 将节点版本设置为 12 或使用 package.json 文件中的分辨率。
第一个解决方案(在你最喜欢的终端):
nvm install 12; nvm use 12
第二个解决方案(在package.json):
"resolutions": {
"**/**/fs-capacitor":"^6.2.0",
"**/graphql-upload": "^11.0.0"
}
这也是我几个月来一直在处理的问题,我认为 apollo 团队真的不喜欢更新他们的依赖项。
因为它是 fs-capacitor 的一个错误,这将有助于我们在这个 issue
中看到
在节点 14.16.1 中为我工作,配置如下:
"resolutions": {
"fs-capacitor": "^6.2.0",
"graphql-upload": "^11.0.0"
}
我需要在“脚本”中添加强制分辨率
"scripts": {
....
"preinstall": "npx npm-force-resolutions"
}
删除 ./node_modules 并使用 npm install 再次安装依赖项。
我已阅读 graphql-upload 文档,但找不到一个可靠的示例来说明如何在 NodeJS 14 上将图形上传与 apollo-server 结合使用。
基于示例应用程序(在旧的 graphql-upload 版本的 apollo-server 上运行,在 NodeJS 14 上失败)和堆栈溢出的答案,我设法创建了一个功能齐全的示例。
原例子:https://github.com/DNature/apollo-upload
我使用了 apollo-server-express,而不是 apollo-server。
使用 NodeJS 14、graphql-upload@12.0.0 和 apollo-server-express@2.25.1:
index.js
import { ApolloServer } from "apollo-server-express";
import express from "express";
import { graphqlUploadExpress } from "graphql-upload";
import typeDefs from "./typeDefs";
import resolvers from "./resolvers";
// Import your database configuration
import connect from "./db";
export default (async function () {
try {
await connect.then(() => {
console.log("Connected To MongoDB Successfully");
});
const server = new ApolloServer({
uploads: false, // Disables the bundled ApolloServer old graphql-upload that doesn't work on NodeJS 14
typeDefs,
resolvers,
});
await server.start();
const app = express();
app.use(graphqlUploadExpress({ maxFileSize: 1000000000, maxFiles: 10 }));
server.applyMiddleware({ app });
await new Promise((resolve) => app.listen({ port: 7000 }, resolve));
console.log(
` Server ready at http://localhost:7000${server.graphqlPath}`
);
} catch (err) {
console.error(err);
}
})();
在typeDefs.gql中需要定义标量上传:
import { gql } from "apollo-server-express";
export default gql`
scalar Upload
type File {
id: ID!
...
在 resolvers.js 中,需要定义上传的解析器:
...
import { GraphQLUpload } from 'graphql-upload';
...
export default {
Upload: GraphQLUpload,
Query: {
hello: () => "Hello world"
},
Mutation: {
...
终于从邮递员上传:
Note: the key 0 is of type File, not Text!
TLDR:默认的 Apollo 服务器文件上传在节点 >=13 中不起作用。通过使用 graphql-upload
服务器文件上传
覆盖 Apollo 的服务器文件上传来修复它
npm install graphql-upload
覆盖 TypeDefs
中的默认 Apollo 上传类型
const typeDefs = gql`
scalar Upload
...
`
覆盖 index.js
中的默认 Apollo 上传类型
const { GraphQLUpload } = require('graphql-upload')
const { graphqlUploadExpress } = require('graphql-upload')
const express = require('express')
const app = express()
app.use(graphqlUploadExpress({
maxFileSize: 10000000,
maxFiles: 10
}))
const server = new ApolloServer({
typeDefs,
resolvers: {
Upload: GraphQLUpload,
...resolvers
}
uploads: false
...
})
server.applyMiddleware({
app
})
我正在尝试使用 Apollo Server 的 Upload
标量直接将文件发送到 S3。我的架构:
const { gql } = require('apollo-server-express')
module.exports = gql`
extend type Mutation {
createPicture(
name: String!
picture: Upload!
): Picture!
}
type Picture {
name: String!
picture: String!
}
`
解析器:
const { combineResolvers } = require('graphql-resolvers')
const isAuthenticated = require('./auth')
const { uploadPhoto } = require('../services/picture')
module.exports = {
Mutation: {
createPicture: combineResolvers(
isAuthenticated,
async (
parent,
{ name, picture = null },
{ models, me }
) => {
const { createReadStream, filename, mimetype, encoding } = await picture
// Does not get past this line
const stream = createReadStream()
uploadPhoto(stream, filename)
const pictureModel = models.Picture.create({
name,
picture
})
return pictureModel
}
)
}
}
但是我的代码错误是这样的:
internal/util.js:55
function deprecated(...args) {
^
RangeError: Maximum call stack size exceeded
at ReadStream.deprecated [as open] (internal/util.js:55:22)
at ReadStream.open ([truncated]/node_modules/fs-capacitor/lib/index.js:90:11)
at _openReadFs (internal/fs/streams.js:123:12)
at ReadStream.<anonymous> (internal/fs/streams.js:116:3)
at ReadStream.deprecated [as open] (internal/util.js:70:15)
at ReadStream.open ([truncated]/node_modules/fs-capacitor/lib/index.js:90:11)
at _openReadFs (internal/fs/streams.js:123:12)
at ReadStream.<anonymous> (internal/fs/streams.js:116:3)
at ReadStream.deprecated [as open] (internal/util.js:70:15)
at ReadStream.open ([truncated]/node_modules/fs-capacitor/lib/index.js:90:11)
at _openReadFs (internal/fs/streams.js:123:12)
at ReadStream.<anonymous> (internal/fs/streams.js:116:3)
at ReadStream.deprecated [as open] (internal/util.js:70:15)
at ReadStream.open ([truncated]/node_modules/fs-capacitor/lib/index.js:90:11)
at _openReadFs (internal/fs/streams.js:123:12)
at ReadStream.<anonymous> (internal/fs/streams.js:116:3)
at ReadStream.deprecated [as open] (internal/util.js:70:15)
at ReadStream.open ([truncated]/node_modules/fs-capacitor/lib/index.js:90:11)
at _openReadFs (internal/fs/streams.js:123:12)
at ReadStream.<anonymous> (internal/fs/streams.js:116:3)
at ReadStream.deprecated [as open] (internal/util.js:70:15)
at ReadStream.open ([truncated]/node_modules/fs-capacitor/lib/index.js:90:11)
注意:我确信图像发送正确,因为 filename
是正确的
原来这是 this graphql-upload
中的错误。降级到节点 12 并已修复(此处列出的解决方案对我没有帮助)
我在节点版本 14 中也出现了这个错误! 我是这样解决的:
安装最新版本的 graphql-upload!
使用 graphqlUploadExpress 中间件定义最大文件限制。
import { graphqlUploadExpress } from "graphql-upload"; const app = express() app.use(graphqlUploadExpress({ maxFileSize: 1000000000, maxFiles: 10 }));
在初始化 ApolloServer 时将上传设置为 false
const server = new ApolloServer({ uploads: false, schema, });
将此添加到 package.json:
"resolutions": {
"**/**/fs-capacitor":"^6.2.0",
"**/graphql-upload": "^11.0.0"
}
来源:https://github.com/jaydenseric/graphql-upload/issues/170#issuecomment-641938198
使用:
"apollo-server": "^2.18.2",
"apollo-server-express": "2.18.2",
"aws-sdk": "^2.771.0",
"express-fileupload": "^1.2.0",
"graphql": "^15.3.0",
"graphql-upload": "^11.0.0",
"fs-capacitor": "^6.2.0",
我通过安装最新的 fs-capacitor
作为依赖来解决这个问题
yarn add fs-capacitor
将此添加到您的 package.json
"resolutions": {
"graphql-upload": "^11.0.0"
}
然后在脚本中添加这个
"scripts": {
....
"preinstall": "npx npm-force-resolutions", //This one
....
}
然后你需要执行 npm install。完成
我已经多次处理这个问题
问题是旧的 graphql-upload 版本 8 更准确地使用节点打开流功能,该功能已弃用,在 13.x 和更旧的节点版本中不再可用。
所以解决方案是您可以使用 nvm 将节点版本设置为 12 或使用 package.json 文件中的分辨率。 第一个解决方案(在你最喜欢的终端):
nvm install 12; nvm use 12
第二个解决方案(在package.json):
"resolutions": {
"**/**/fs-capacitor":"^6.2.0",
"**/graphql-upload": "^11.0.0"
}
这也是我几个月来一直在处理的问题,我认为 apollo 团队真的不喜欢更新他们的依赖项。
因为它是 fs-capacitor 的一个错误,这将有助于我们在这个 issue
中看到在节点 14.16.1 中为我工作,配置如下:
"resolutions": {
"fs-capacitor": "^6.2.0",
"graphql-upload": "^11.0.0"
}
我需要在“脚本”中添加强制分辨率
"scripts": {
....
"preinstall": "npx npm-force-resolutions"
}
删除 ./node_modules 并使用 npm install 再次安装依赖项。
我已阅读 graphql-upload 文档,但找不到一个可靠的示例来说明如何在 NodeJS 14 上将图形上传与 apollo-server 结合使用。 基于示例应用程序(在旧的 graphql-upload 版本的 apollo-server 上运行,在 NodeJS 14 上失败)和堆栈溢出的答案,我设法创建了一个功能齐全的示例。
原例子:https://github.com/DNature/apollo-upload
我使用了 apollo-server-express,而不是 apollo-server。
使用 NodeJS 14、graphql-upload@12.0.0 和 apollo-server-express@2.25.1:
index.js
import { ApolloServer } from "apollo-server-express";
import express from "express";
import { graphqlUploadExpress } from "graphql-upload";
import typeDefs from "./typeDefs";
import resolvers from "./resolvers";
// Import your database configuration
import connect from "./db";
export default (async function () {
try {
await connect.then(() => {
console.log("Connected To MongoDB Successfully");
});
const server = new ApolloServer({
uploads: false, // Disables the bundled ApolloServer old graphql-upload that doesn't work on NodeJS 14
typeDefs,
resolvers,
});
await server.start();
const app = express();
app.use(graphqlUploadExpress({ maxFileSize: 1000000000, maxFiles: 10 }));
server.applyMiddleware({ app });
await new Promise((resolve) => app.listen({ port: 7000 }, resolve));
console.log(
` Server ready at http://localhost:7000${server.graphqlPath}`
);
} catch (err) {
console.error(err);
}
})();
在typeDefs.gql中需要定义标量上传:
import { gql } from "apollo-server-express";
export default gql`
scalar Upload
type File {
id: ID!
...
在 resolvers.js 中,需要定义上传的解析器:
...
import { GraphQLUpload } from 'graphql-upload';
...
export default {
Upload: GraphQLUpload,
Query: {
hello: () => "Hello world"
},
Mutation: {
...
终于从邮递员上传:
Note: the key 0 is of type File, not Text!
TLDR:默认的 Apollo 服务器文件上传在节点 >=13 中不起作用。通过使用 graphql-upload
服务器文件上传
npm install graphql-upload
覆盖 TypeDefs
const typeDefs = gql`
scalar Upload
...
`
覆盖 index.js
const { GraphQLUpload } = require('graphql-upload')
const { graphqlUploadExpress } = require('graphql-upload')
const express = require('express')
const app = express()
app.use(graphqlUploadExpress({
maxFileSize: 10000000,
maxFiles: 10
}))
const server = new ApolloServer({
typeDefs,
resolvers: {
Upload: GraphQLUpload,
...resolvers
}
uploads: false
...
})
server.applyMiddleware({
app
})