Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Amplify PubSub - Production builds do not open websocket #7554

Open
3 tasks done
npellegrin opened this issue Apr 16, 2023 · 4 comments
Open
3 tasks done

Amplify PubSub - Production builds do not open websocket #7554

npellegrin opened this issue Apr 16, 2023 · 4 comments
Assignees
Labels
amplify/js Issues tied to JS PubSub

Comments

@npellegrin
Copy link

npellegrin commented Apr 16, 2023

Before opening, please confirm:

JavaScript Framework

Vue

Amplify APIs

PubSub

Amplify Categories

Not applicable

Environment information

# Put output below this line


Describe the bug

This may be related to aws-amplify/amplify-js#10829.
It could be related to my implementation of the Amplify initialization in Quasar.

When using the PubSub module, websockets are not opened by the framework with production builds. There is no error message.
Development builds works properly.

Expected behavior

Websockets should be opened on both development build and production builds.

Reproduction steps

I have a Vue.js application, built with Vite and Quasar. Versions are:

  "dependencies": {
    "@aws-amplify/ui-vue": "^3.1.7",
    "@quasar/extras": "^1.0.0",
    "aws-amplify": "^5.0.14",
    "graphql-tag": "^2.12.6",
    "pinia": "^2.0.28",
    "quasar": "^2.6.0",
    "vue": "^3.2.45",
    "vue-router": "^4.1.6"
  },
  "devDependencies": {
    "@quasar/app-vite": "^1.0.0",
    "autoprefixer": "^10.4.2",
    "eslint": "^8.10.0",
    "eslint-config-prettier": "^8.1.0",
    "eslint-plugin-vue": "^9.0.0",
    "postcss": "^8.4.14",
    "prettier": "^2.5.1"
  },

I setup Amplify during the Quasar boot and the Amplify init looks like this:

import { boot } from "quasar/wrappers";

import { Amplify } from "aws-amplify";
import { AWSIoTProvider } from "@aws-amplify/pubsub/lib/Providers";

export default boot(() => {
  Amplify.configure({
    Auth: {
      identityPoolId: '',
      region: '',
      identityPoolRegion: '',
      userPoolId: '',
      userPoolWebClientId: '',
      mandatorySignIn: true,
    }
  });

  Amplify.addPluggable(
    new AWSIoTProvider({
      aws_pubsub_region: '....',
      aws_pubsub_endpoint: '....'
    })
  );
});

And the subscription is performed like this:

PubSub.subscribe('my-topic').subscribe({
  next: (data) => handleNotification(data),
  error: (error) => console.error(error),
  close: () => console.debug("Subscription closed"),
  complete: () => console.debug("Subscription complete"),
});

Also, I have in my index.html and quasar.config.js the magic lines to make Amplify work with production packaging:

index.html

    <script>
      window.global = window;
      var exports = {};
    </script>

quasar.config.js:

      extendViteConf(viteConf, { isClient, isServer }) {
        Object.assign(viteConf.resolve.alias, {
          "./runtimeConfig": "./runtimeConfig.browser",
        });

When testing the application with quasar dev, the subscription is performed.
With a production build, the websocket request is never opened by the web browser, but no error message is shown.

Additional information and screenshots

With Amplify.Logger.LOG_LEVEL = 'DEBUG' activated, production builds have no reference to MqttOverWSProvider in the logs, when dev builds properly show the MqttOverWSProvider, and it work.

I found a possible workaround, it seems that adding the AWSIoTProvider pluggable directly using the PubSub API instead of using the Amplify API API works:

  PubSub.addPluggable(
    new AWSIoTProvider({
      aws_pubsub_region: '....',
      aws_pubsub_endpoint: '....'
    })
  );
@npellegrin
Copy link
Author

I managed to put a breakpoint in the Amplify.addPluggable function call at runtime, and the bug seems to be related to the _components list of the Amplify object not having a PubSub object instance. This explain why the addPluggable instruction is never forwarded to PubSub component, but I did not managed to understand how the _component should have been populated at this step.

Below, the production-minified code of the Amplify function, with some watchers :
image
The screenshot correspond to this line is source code: https://github.com/aws-amplify/amplify-js/blob/e1b0b5be3e8ccb3c76e8e2e2f43f910d40d73254/packages/core/src/Amplify.ts#L80

@npellegrin
Copy link
Author

npellegrin commented Apr 16, 2023

Ok, I found it... The _componentsattribute is populated when register() function is called in the Amplify object. This call is performed automatically uppon import, at : https://github.com/aws-amplify/amplify-js/blob/5147c5ce555d042722e2888fc423430f517b91b7/packages/pubsub/src/PubSub.ts#L177

This import is clearly specified in the documentation, and the initialization should be performed as this:
image

However, following strictly this documentation will not work in production builds, because minifiers will drop the unused PubSub import because it is actually never used in my boot() function (it is only used when performing subscribe later in the app), consequently, the Amplify.addPluggable fail silently and nothing is really plugged to the PubSub module.

I fixed my app by forcing the registration before calling addPluggable, or artificially using the PubSub module in my boot function. Below the both working hacks:

  PubSub.getModuleName();
  Amplify.addPluggable(
    new AWSIoTProvider({
      aws_pubsub_region: '',
      aws_pubsub_endpoint: ''
    })
  );
  Amplify.register(PubSub);
  Amplify.addPluggable(
    new AWSIoTProvider({
      aws_pubsub_region: '',
      aws_pubsub_endpoint: ''
    })
  );

I guess the documentation should be updated to warn about this side effect, or the behavior of addPluggable may be improved to prevent minifiers missing the register() function call before Amplify.addPluggable.

@EandrewJones
Copy link

Thanks for reporting this @npellegrin and digging into the problem/solution.

I am encountering the same issue with vite production build and react. The above fix(es) work for me as well.

versions

"aws-amplify": "^5.2.2"
"vite": "^3.2.3"

@cwomack
Copy link
Member

cwomack commented May 8, 2024

Moving this issue to the amplify-docs repo. There needs to be updates to both the v5 and the v6 code examples for PubSub based on the workarounds and details in this issue.

@cwomack cwomack transferred this issue from aws-amplify/amplify-js May 8, 2024
@cwomack cwomack added the amplify/js Issues tied to JS label May 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
amplify/js Issues tied to JS PubSub
Projects
None yet
Development

No branches or pull requests

4 participants