Describe the bug
Per the docs https://graphql-ruby.org/javascript_client/apollo_subscriptions#apollo-2--actioncable I have import { ActionCableLink } from 'graphql-ruby-client'; in my react typescript project. However, I get
Module not found: Error: Can't resolve 'fs' in '/Users/me/project/node_modules/graphql-ruby-client/dist/sync'
@ /Users/me/project/node_modules/graphql-ruby-client/dist/sync/prepareProject.js 7:27-40
@ /Users/me/project/node_modules/graphql-ruby-client/dist/sync/generateClient.js
@ /Users/me/project/node_modules/graphql-ruby-client/dist/index.js
Versions
graphql version: (1.9.6)
rails (or other framework): (5.2.3)
other applicable versions (graphql-batch, etc)
Not relevant to the backend side, so for React,
GraphQL schema
Trying to implement subscriptions but can't even import the module.
Steps to reproduce
Expected behavior
A working app
Actual behavior
Getting that "fs" cannot be found. Adding it as a dependency does not fix the problem, but I shouldn't have to in the first place.
Click to view exception backtrace
Uncaught Error: Cannot find module 'fs'
at webpackMissingModule (glob.js:43)
at Object.<anonymous> (glob.js:43)
at Object.../../../node_modules/glob/glob.js (glob.js:790)
at __webpack_require__ (bootstrap:769)
at fn (bootstrap:129)
at Object.../../../node_modules/graphql-ruby-client/dist/sync/generateClient.js (generateClient.js:7)
at __webpack_require__ (bootstrap:769)
at fn (bootstrap:129)
at Object.../../../node_modules/graphql-ruby-client/dist/sync/index.js (index.js:7)
at __webpack_require__ (bootstrap:769)
at fn (bootstrap:129)
at Object.../../../node_modules/graphql-ruby-client/dist/index.js (index.js:6)
at __webpack_require__ (bootstrap:769)
at fn (bootstrap:129)
at Module../src/apollo-client/index.ts (index.ts:1)
at __webpack_require__ (bootstrap:769)
at Object.0 (index.ts:2)
at __webpack_require__ (bootstrap:769)
at bootstrap:907
at bootstrap:907
Weird. fs is a Node.JS module. I guess the require(...) arrangement I chose isn't good, because it mixes server-side and client-side code in an incompatible way.
I recommend that you try 1.6.8 -- the code is basically the same, but it's before I re-wrote it in typescript and broke a bunch of things 馃檲
Hello,
I tried to use previous version as suggested and I don't have that issue anymore, thank you very much!.
But then app still broke. I am trying to use ActionCableLink within a React Native app but I cannot find a proper way to set the auth headers for Subscription endpoint.
in myApolloClient.ts after all the Apollo graphql configuration (query and mutations are working properly) I show you the piece of code which uses ActionCableLink in order to connect the endpoint for Subscriptions.
const link = split(
({query}) => {
const definition = getMainDefinition(query);
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
);
},
new ActionCableLink({
cable: async () => {
const url = await websocketUrl();
return ActionCable.createConsumer(url);
}
}),
httpAuthLink
);
Compilation error is: "() => Promise
The problem is websocketUrl function, which is async due to headers I am fetching from AsyncStorage which is like localstorage but for React Native. I paste the code for reference:
in myApolloClient.ts
const websocketUrl = async () => {
const {headers} = await getHeaders();
return `wss://company-rails-backend.io/subscriptions?` +
`access-token=${encodeURIComponent(headers['access-token'])}&` +
`client=${encodeURIComponent(headers['client'])}&` +
`token-type=${headers['token-type']}&` +
`expiry=${headers['expiry']}&` +
`uid=${headers['uid']}`;
};
In utils.ts file
Even other alternative suggestion might be very helpful, I have already spent all today to find a way :( 馃檹馃徎 Cheers,export const getHeaders = async () => {
const headers: any = {};
const accessToken = await AsyncStorage.getItem('access-token');
if (accessToken) {
headers['access-token'] = accessToken;
}
// similar code for the rest of the headers
return {headers};
}
Do you know some way to let your ActionCableLink constructor work in order to set properly the websocket url with all the headers appended?
Unfortunately I cannot declare an async module for my ApolloClient instance because it fails
Andrea
Updating my webpack config did the tricks:
node: {
fs: 'empty',
},
ref: https://github.com/webpack-contrib/css-loader/issues/447#issuecomment-285598881
i think the sync stuff should likely be a separate module since it's only usable server-side (ie, graphql-ruby-sync or something)?
I used Apollo Lazy Link https://github.com/dai-shi/apollo-link-lazy to achieve it馃憣
i think the
syncstuff should likely be a separate module since it's only usable server-side (ie,graphql-ruby-syncor something)?
please extract sync from to separate server-side module/package, it cause to fail to compile in AOT in client-side app.
Most helpful comment
Weird.
fsis a Node.JS module. I guess therequire(...)arrangement I chose isn't good, because it mixes server-side and client-side code in an incompatible way.I recommend that you try 1.6.8 -- the code is basically the same, but it's before I re-wrote it in typescript and broke a bunch of things 馃檲