apollo-link-ws loads backend modules when using it in the browser
Opened this issue · 1 comments
Expected Behavior
apollo-link-ws package does not crash whole web app.
Actual Behavior
apollo-link-ws crashes app due to backed packages being required.
A simple reproduction
Use the mentioned package's export "WebSocketLink" in frontend code.
Monkey patch for front end, will break backend ofcourse
In node_modules/apollo-link-ws/lib/webSocketLink.js
change:
var subscriptions_transport_ws_1 = require("subscriptions-transport-ws");
to:
var subscriptions_transport_ws_1 = require("subscriptions-transport-ws/browser/client.js");
Version
apollo-link-ws 1.0.19
How i eventually fixed it
I just created a file with this content (fetched from the apollo-link-ws repo and removed some types and updated the import path for 'subscriptions-transport-ws', https://raw.githubusercontent.com/apollographql/apollo-link/master/packages/apollo-link-ws/src/webSocketLink.ts
)
import { ApolloLink, Operation, FetchResult, Observable } from 'apollo-link'
import { SubscriptionClient } from 'subscriptions-transport-ws/dist/client'
export class WebSocketLink extends ApolloLink {
private subscriptionClient
constructor(paramsOrClient) {
super()
if (paramsOrClient instanceof SubscriptionClient) {
this.subscriptionClient = paramsOrClient
} else {
this.subscriptionClient = new SubscriptionClient(
paramsOrClient.uri,
paramsOrClient.options,
paramsOrClient.webSocketImpl,
)
}
}
public request(operation: Operation): Observable<FetchResult> | null {
return this.subscriptionClient.request(operation) as Observable<FetchResult>
}
}
Encountered this as well. I can provide another potential solution and more context.
(Potential) Alternate Solution - Webpack
Check your webpack config's resolve.mainFields
. Reference
When the target property is set to webworker, web, or left unspecified:
module.exports = {
resolve: {
mainFields: ['browser', 'module', 'main']
}
};
When referenced against subscriptions-transport-ws, webpack should use dist/client.js
.
In my case, the webpack config defined a different order in which main was preferred. Changing that resolved the issue.
Background
Tracked down this line causing errors: import { WebSocketLink } from 'apollo-link-ws'
.
My terminal has a bunch of different errors in the format of:
ERROR in ./node_modules/graphql/index.mjs 42:0-48:205
Can't reexport the named export 'visitInParallel' from non EcmaScript module (only default export is available)
and then in the browser:
Error: Cannot find module 'tls' at webpackMissingModule
I tried the above solution, rewriting the class and importing from 'subscriptions-transport-ws/dist/client'
directly, and it works. But I was unsatisfied.
The reason I was unsatisfied is because I have other implementations on top of both create react app and nextjs that import apollo-link-ws the same way without issue. I spent a while debugging before noticing the package.json's browser property and checking my webpack config.