Subscriptions-transport-ws: Subcription is not exported by node_modules/subscriptions-transport-ws/dist/index.js

Created on 12 May 2019  Â·  9Comments  Â·  Source: apollographql/subscriptions-transport-ws

I'm using https://github.com/sveltejs/template with rollup (https://github.com/sveltejs/template/blob/master/rollup.config.js).

During compile I get this error:
Error: "Subcription is not exported by node_modules/subscriptions-transport-ws/dist/index.js"

This I think I fixed with:
https://github.com/rollup/rollup-plugin-commonjs#custom-named-exports

commonjs({
    namedExports: {
        './node_modules/subscriptions-transport-ws/dist/index.js': ['SubscriptionClient']
    }
}),

Now it compiles but when I open site chrome says:
"Uncaught ReferenceError: events is not defined" in main.js

I created a simple repo: https://codesandbox.io/s/zn1mnon8jl.

If you open it in codesandbox it works! But if you download as a zip and execute npm i && npm run dev you can see the problem.

_Originally posted by @jesperordrup in https://github.com/timhall/svelte-apollo/issues/10#issuecomment-491517274_

Rollup hates us novices.

Is SubscriptionClient correctly exported and imported in apollo-link-ws?

Most helpful comment

@praveenweb amazing. It builds. Thanks.

All 9 comments

If I add:

    commonjs({
      namedExports: {
        'node_modules/subscriptions-transport-ws/dist/index.js': ['SubscriptionClient']
      }
    }),

the error now becomes:

index.js → public/bundle.js...
(!) Mixing named and default exports
Consumers of your bundle will have to use bundle['default'] to access the default export, which may not be what you want. Use `output.exports: 'named'` to disable this warning
(!) Missing shims for Node.js built-ins
Creating a browser bundle that depends on 'events', 'https', 'http', 'url', 'zlib' and 'stream'. You might need to include https://www.npmjs.com/package/rollup-plugin-node-builtins
(!) Unresolved dependencies
https://rollupjs.org/guide/en#warning-treating-module-as-external-dependency
events (imported by node_modules\ws\lib\websocket.js, node_modules\ws\lib\websocket-server.js,  commonjs-external-events)
crypto (imported by node_modules\ws\lib\websocket.js, node_modules\ws\lib\websocket-server.js, node_modules\ws\lib\sender.js,  commonjs-external-crypto)
https (imported by node_modules\ws\lib\websocket.js,  commonjs-external-https)
net (imported by node_modules\ws\lib\websocket.js,  commonjs-external-net)
http (imported by node_modules\ws\lib\websocket.js, node_modules\ws\lib\websocket-server.js,  commonjs-external-http)
tls (imported by node_modules\ws\lib\websocket.js,  commonjs-external-tls)
url (imported by node_modules\ws\lib\websocket.js, node_modules\ws\lib\websocket-server.js,  commonjs-external-url)
stream (imported by node_modules\ws\lib\receiver.js,  commonjs-external-stream)
zlib (imported by node_modules\ws\lib\permessage-deflate.js,  commonjs-external-zlib)
bufferutil (imported by node_modules\ws\lib\buffer-util.js,  commonjs-external-bufferutil)
utf-8-validate (imported by node_modules\ws\lib\validation.js,  commonjs-external-utf-8-validate)
(!) Missing global variable names
Use output.globals to specify browser global variable names corresponding to external modules
events (guessing 'events')
crypto (guessing 'crypto')
https (guessing 'https')
http (guessing 'http')
net (guessing 'net')
tls (guessing 'tls')
url (guessing 'url')
zlib (guessing 'zlib')
bufferutil (guessing 'bufferutil')
stream (guessing 'stream')
utf-8-validate (guessing 'utf8Validate')
created public/bundle.js in 13.8s

What a mess. I'm using just web oriented libraries, why it complains about nodejs dependencies?

What to do now?

I think apollo-link-ws or subscriptions-transport-ws should write a wiki/FAQ about rollup.

As also @JoviDeCroock here https://github.com/apollographql/apollo-link/issues/1043#issuecomment-491616593 said:

The issue now seems to be that events is undefined.

I added these in rollup.config.js:

import builtins from 'rollup-plugin-node-builtins'
import globals from 'rollup-plugin-node-globals'
...
plugins: [
  globals(),
  builtins(),

and all the previous errors are gone.

Now in browser I got:

Uncaught ReferenceError: exports is not defined
    at client.js:45

It complains about this line (I think):

Object.defineProperty(exports, "__esModule", { value: true });

Some people have made a simil-fork package to solve the Rollup problem temporarily: https://github.com/lunchboxer/graphql-subscriptions-client.

Please, this requires your attention.

I have a sample app working with GraphQL subscriptions here - https://github.com/hasura/graphql-engine/tree/master/community/sample-apps/svelte-apollo
It uses a slightly modified rollup config with rollup-plugin-node-resolve plugin to make it work.

Ideally if subscriptions-transport-ws exports an esm module, this wouldn't have been an issue. Hoping to get this PR merged.

@praveenweb amazing. It builds. Thanks.

for anyone else looking for a solution to this, I found something along these lines to work (in a sapper environment):

But dont' expect this to work with AppSync, the websockets scheme is different to apollo's!

<script>
    import { ApolloClient, HttpLink, ApolloLink, split } from "@apollo/client/core";
    import { SubscriptionClient } from 'subscriptions-transport-ws/dist/client.js';
    import { getMainDefinition } from '@apollo/client/utilities';
    import { InMemoryCache } from '@apollo/client/cache';
    import { query, subscribe } from 'svelte-apollo';
    import { listTodos } from './_graphql/queries.js'
    import { onUpdateTodo } from './_graphql/subscriptions.js'

    const cache = new InMemoryCache();

    const headers = {
        'authorisation': 'xxx'
    }
    const getHeaders = () => {
        return headers;
    };

    class WebSocketLink extends ApolloLink {
        constructor(paramsOrClient) {
            super();
            if (paramsOrClient instanceof SubscriptionClient) {
                this.subscriptionClient = paramsOrClient;
            }
            else {
                this.subscriptionClient = new SubscriptionClient(paramsOrClient.uri, paramsOrClient.options, paramsOrClient.webSocketImpl);
            }
        }
        request(operation) {
            return this.subscriptionClient.request(operation);
        }
    }

    const wsLink = new WebSocketLink({
        uri: `wss://xxxx/graphql`,
        options: {
            reconnect: true,
            lazy: true,
            connectionParams: () => {
                return { headers: getHeaders() };
            },
        },
    });

    const httpLink = new HttpLink({
        uri: 'https://yyyy/graphql',
        headers: getHeaders()
    });

    const link = split(
        ({ query }) => {
            const { kind, operation } = getMainDefinition(query);
            return kind === "OperationDefinition" && operation === "subscription";
        },
        wsLink,
        httpLink
    );

    export const client = new ApolloClient({
        link,
        cache
    });

    const todos = query(client, { query: listTodos });

    const subs = subscribe(client, { query: onUpdateTodo })
</script>
<div>
    <h2>Query</h2>
     {#await $todos}
        Loading...
        {:then result} 
        {#each result.data.listTodos.items as todo}
            <p>{todo.name} / {todo.description}</p>
         {/each} 
       {:catch error}
        Error: {error}
     {/await}
     <h2>Subscriptions</h2>
     {#await $subs} 
        Loading...
        {:then result}
        {#each result.data.listTodos.items as todo}
           <p>{todo.name} / {todo.description}</p>
        {/each}
      {:catch error} Error: {error} 
     {/await}
</div>

facing same issue. Any fix ?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

prokher picture prokher  Â·  5Comments

farzd picture farzd  Â·  3Comments

anilanar picture anilanar  Â·  5Comments

KaiWedekind picture KaiWedekind  Â·  4Comments

thebigredgeek picture thebigredgeek  Â·  5Comments