首页 > 解决方案 > Apollo 上传文件,createReadStream 不是函数

问题描述

我试图让这个工作好几天,现在在哪里。我确实相信客户端功能正常,但我不能百分百确定。我知道服务器上的解析器正在被调用。在某一时刻,我能够解构解析器中的文件参数。但是现在当我解构时,我变得不确定。不确定这是怎么回事,它在某一时刻解构得很好。客户端项目设置为连接到两个不同的 GraphQL 服务器,一个用于标准数据库和订阅,另一个用于文件上传器。这就是为什么我将订阅留在客户的依赖中。

我想说谢谢你花时间看这个。

我的服务器版本信息

"@graphql-tools/schema": "^7.1.5",
"apollo-cache-inmemory": "^1.6.6",
"apollo-server-express": "^2.25.0", 
"express": "^4.17.1",
"express-jwt": "^6.0.0", 
"graphql": "^15.5.0",
"graphql-middleware": "^6.0.10",
"graphql-shield": "^7.5.0",
"graphql-upload": "^12.0.0", 

我的主文件

import { ApolloError, ApolloServer, makeExecutableSchema } from "apollo-server-express"
import { applyMiddleware } from "graphql-middleware"
import express from "express" 

import { graphqlUploadExpress } from 'graphql-upload' 
import makeDir from 'make-dir'
     
const app = express()
const cors = require('cors')

 
 

app.use(cors())

const bodyParser = require('body-parser') 
 

app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.use(graphqlUploadExpress({ maxFileSize: 10000000, maxFiles: 10 }));


const apolloServer = new ApolloServer({ 
    uploads: false, 
    ...
    schema: applyMiddleware(
        makeExecutableSchema({ typeDefs, resolvers }),
        permissions
    ),
    
    context: ({ req, res }) => {
        ...     
    },
    
});

    
apolloServer.applyMiddleware({ app });
...

async function StartServer() { 
    await makeDir(UPLOAD_DIR) 
    app.listen({ host: HOST, port: PORT }, () => { 
        console.log(` 
        
        Apollo File Server ready at http://${HOST}:${PORT}${apolloServer.graphqlPath}  
        Started at ${datetime}  
        isDevelopmentMode ${isDevelopmentMode}        
        `)
    });
}

StartServer()

我的架构

type File {
    name: String!
    size: Int!
}
    
extend type Mutation {   
    singleUpload(file: Upload!): File!, 
}

我的解析器

singleUpload: async (parent, { file }) => {
    console.log('singleUpload------------------------------------------------------------------------------>>>', file)
    console.log('singleUpload------------------------------------------------------------------------------>>> 0')
    const { createReadStream, filename, mimetype, encoding } = await file;
    console.log('singleUpload------------------------------------------------------------------------------>>> 1', filename)
    const stream = createReadStream();
    console.log('singleUpload------------------------------------------------------------------------------>>> 2')
    const pathName = `${UPLOAD_DIR}${filename}`;
    console.log('singleUpload------------------------------------------------------------------------------>>> 3')
    await stream.pipe(fs.createWriteStream(pathName));

    console.log('singleUpload------------------------------------------------------------------------------>>> 4')

    return {
            name: `http://localhost:4001/images/${filename}`,
            size: 1,
    };
},

我的客户端版本信息

    "@apollo/client": "^3.2.7",
    "@apollo/react-hoc": "^4.0.0",
    "@apollo/react-hooks": "^4.0.0", 
    "@graphql-codegen/introspection": "^1.18.1",
    "@graphql-codegen/schema-ast": "^1.18.1",
    "@graphql-tools/load-files": "^6.2.5",
    "@graphql-tools/merge": "^6.2.6", 
    "apollo-boost": "^0.4.9",
    "apollo-link-ws": "^1.0.20",
    "apollo-upload-client": "^16.0.0", 
    "graphql": "^14.7.0",
    "graphql-scalars": "^1.7.0", 
    "react": "^16.14.0",
    "react-apollo": "^3.1.5",
    "react-app-rewire-define-plugin": "^1.0.0",
    "react-app-rewired": "^2.1.8", 
    "react-dom": "^16.14.0", 
    "react-router-dom": "^5.2.0",
    "react-scripts": "^3.4.1", 
    "subscriptions-transport-ws": "^0.9.18", 
    "typescript": "^3.7.3", 

阿波罗客户端

const uploadLink = createUploadLink({
    uri: 'http://localhost:4001/graphql', // Apollo Server is served from port 4000
    headers: {
        "keep-alive": "true",
        'content-type': 'application/json', 
        ...((accessToken !== undefined && accessToken !== null) ? { Authorization: `Bearer ${accessToken}` } : {}),
        ...((accessToken !== undefined && accessToken !== null) ? { 'x-token': accessToken } : {}),
        ...((refreshToken !== undefined && refreshToken !== null) ? { 'x-refresh-token': refreshToken } : {}),
    }
})

const clientUpload = new ApolloClient({
    cache: cache,
    link: uploadLink
})

上传器组件

const mutUploadFile = gql`
mutation singleUpload($file: Upload!) { 
singleUpload(file: $file) {
    name
    #filename 
    #mimetype 
    #encoding 
    #url 
}
}` 

export function FileUploadSimpleA() {  
    const onChange = ((e: any) => {
        console.log( 'onChange-------------------------')
        const file = e.target.files[0]
        console.log('file:', file)
        if (file) 
            clientUpload.mutate({
                mutation: mutUploadFile,
                variables: {
                    file: file
                }
            })
                .then(result => { 
                    console.log( 'then-------------------------')
                    console.log(result) 
                    clientUpload.resetStore();
                })
                .catch(error => { 
                    console.log( 'catch-------------------------')
                    console.log(error) 
                }
            );
        });
     
    return <input type="file" required onChange={onChange} />;
}

 
export default FileUploadSimpleA

浏览器控制台

fileUploadSimple.tsx:50 onChange-------------------------
fileUploadSimple.tsx:52 file:: File {name:
"322abcbafe59a52481e6a0b6b84ffbc4.jpg", lastModified: 1614644398495, lastModifiedDate: Mon Mar 01 2021 18:19:58 GMT-0600 (Central Standard Time), webkitRelativePath: "", size: 68817, …} 
fileUploadSimple.tsx:66 catch------------------------- 
fileUploadSimple.tsx:67 Error: createReadStream is not a function

标签: node.jsreactjsgraphqlapollo

解决方案


推荐阅读