aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.42k stars 2.12k forks source link

Amplify and PubSub imports break React applications since `>4.3.30` #10295

Closed louis-young closed 2 years ago

louis-young commented 2 years ago

Before opening, please confirm:

JavaScript Framework

React

Amplify APIs

PubSub

Amplify Categories

No response

Environment information

I have tested this on MacOS, Windows and statically deployed to S3.

``` System: OS: macOS 12.5.1 CPU: (8) arm64 Apple M1 Memory: 130.52 MB / 8.00 GB Shell: 5.8.1 - /bin/zsh Binaries: Node: 16.13.1 - /opt/homebrew/Cellar/node@16/16.13.1/bin/node Yarn: 1.22.17 - /opt/homebrew/bin/yarn npm: 8.1.2 - /opt/homebrew/Cellar/node@16/16.13.1/bin/npm Browsers: Chrome: 105.0.5195.52 Safari: 15.6.1 npmPackages: @aws-amplify/pubsub: ^4.5.2 => 4.5.2 aws-amplify: ^4.3.34 => 4.3.34 react: ^18.2.0 => 18.2.0 (18.1.0) react-dom: ^18.2.0 => 18.2.0 react-scripts: 5.0.1 => 5.0.1 npmGlobalPackages: gatsby-cli: 4.4.0 n: 7.3.1 npm: 8.5.5 serverless: 2.59.0 ts-node: 9.1.1 typescript: 4.2.4 yarn: 1.22.17 ```

Describe the bug

An error is thrown that prevents anything from being rendered in React applications when importing the Amplify and AWSIoTProvider classes. This has happened since aws-amplify version >4.3.30.

Expected behavior

The application renders as it did before with aws-amplify version <4.3.30.

Reproduction steps

  1. Clone https://github.com/louis-young/aws-amplify-import-issue-investigation.
  2. Run npm install in the project root.
  3. Run npm start in the project root.
  4. Notice the broken application and the error message in the console.

Code Snippet

Minimal reproducible example: https://github.com/louis-young/aws-amplify-import-issue-investigation

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

Amplify.addPluggable(
  new AWSIoTProvider({
    aws_pubsub_region: "...",
    aws_pubsub_endpoint: "...",
  })
);
Working import ```js import Amplify from "aws-amplify"; import { AWSIoTProvider } from "@aws-amplify/pubsub"; ```
Broken imports ```js import { Amplify } from "aws-amplify"; import { AWSIoTProvider } from "@aws-amplify/pubsub"; ... import { AWSIoTProvider } from "@aws-amplify/pubsub"; import Amplify from "aws-amplify"; ... import { Amplify } from "aws-amplify/core"; import { AWSIoTProvider } from "@aws-amplify/pubsub"; ... import { AWSIoTProvider } from "@aws-amplify/pubsub"; import { Amplify } from "aws-amplify/core"; ```

Log output

``` index.ts:48 Uncaught TypeError: Object prototype may only be an Object or null: undefined at setPrototypeOf () at extendStatics (index.ts:48:1) at __extends (index.ts:48:1) at AWSAppSyncProvider.ts:24:1 at ./node_modules/@aws-amplify/pubsub/lib-esm/Providers/AWSAppSyncProvider.js (AWSAppSyncProvider.ts:204:1) at options.factory (react refresh:6:1) at __webpack_require__ (bootstrap:24:1) at fn (hot module replacement:62:1) at ./node_modules/@aws-amplify/pubsub/lib-esm/PubSub.js (index.ts:16:1) at options.factory (react refresh:6:1) ```

aws-exports.js

No response

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

As this occurred after a patch update, I'm not sure if this is a bug or if we're doing something wrong.

I have reproduced this in our application, in a simple Create React App application and a Vite React application. These tools use different module bundlers that are written in different languages and work differently.

This happens with a multitude of import combinations, including using the monolith aws-amplify package and also the modular @aws-amplify/core and @aws-amplify/pubsub packages.

The only way I've been able to resolve this is by importing the deprecated default export of the Amplify class in a specific order, before importing the AWSIoTProvider class.

Weirdly, this works in the CodeSandbox runtime environment but not when running locally on a development server. It also doesn't work after being built and served locally.

Please could you let me know what's happening here?

Thanks in advance 🙂

hacor commented 2 years ago

Hello @louis-young

Same happens here using a Quasar application (Vue 3) when initializing PubSub module. The error is quite vague and seems to involve AWSAppSyncProvider:

vue-router.mjs?6605:3441 TypeError: Object prototype may only be an Object or null: undefined
    at setPrototypeOf (<anonymous>)
    at extendStatics (AWSAppSyncProvider.js?7449:6:1)
    at __extends (AWSAppSyncProvider.js?7449:9:1)
    at eval (AWSAppSyncProvider.js?7449:89:1)
    at eval (AWSAppSyncProvider.js?7449:285:1)
    at ./node_modules/@aws-amplify/pubsub/lib-esm/Providers/AWSAppSyncProvider.js (vendor.js:535:1)
    at __webpack_require__ (app.js:248:33)
    at fn (app.js:514:21)
    at eval (PubSub.js:11:68)
    at ./node_modules/@aws-amplify/pubsub/lib-esm/PubSub.js (vendor.js:612:1)

I narrowed it down to this piece of code:

const awsiotprodvider = new AWSIoTProvider({
        aws_pubsub_region: region,
        aws_pubsub_endpoint: 'wss://************.iot.eu-central-1.amazonaws.com/mqtt'
      })

Any help would really be appreciated!

Best!

louis-young commented 2 years ago

Hi @hacor

The only way I was able to temporarily resolve it was to use the deprecated Amplify default export and to ensure that this was imported above the AWSIoTProvider like this:

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

This seems brittle, imports the deprecated export and given the error was seemingly introduced after a patch update, I don't think this is a viable solution. We have chosen to not update Amplify until we can figure out what's going on.

Hopefully, we'll have an official answer soon 🙂

abdallahshaban557 commented 2 years ago

Thank you for the details on the issue. Our team will investigate this and provide feedback on this Github issue!

louis-young commented 2 years ago

Thank you for the details on the issue. Our team will investigate this and provide feedback on this Github issue!

No problem at all, thank you for the great library 🙂

stocaaro commented 2 years ago

Your sample app was very helpful in reproducing/testing to get this fixed. I have verified that the PR above resolves the issue in the sample app.

louis-young commented 2 years ago

Your sample app was very helpful in reproducing/testing to get this fixed. I have verified that the PR above resolves the issue in the sample app.

Amazing, thanks for getting on this so quickly!

stocaaro commented 2 years ago

Hello @louis-young,

The posted fix solved the problem. I used your steps above to validate with the caveat that I had to run npm update to get the updated versions of the library.

I'm going to resolve it. Feel free to reopen if you find there are still related issues. I had expected this fix to work for this related Vue issue (#10287), however am still able to reproduce the problem in Vue, so will be chasing that down further in that issue.

Regards, Aaron

louis-young commented 2 years ago

Hi @stocaaro, this appears to be fixed in the latest release 🎉 thanks for getting this sorted so quickly