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

fix(aws-amplify): Amplify.register is called per-instance, not per-import #6844

Conversation

ericclemmons
Copy link
Contributor

@ericclemmons ericclemmons commented Sep 21, 2020

Issue #, if available: Fixes #6761, Fixes #6836

Introduced by #6146, Amplify.register was moved to per-import (so that Amplify.Auth was always the same singleton) rather than per-instance (so that each req creating new Auth on the server wouldn't create memory leaks for the lifetime of the server!).

withSSRContext explicitly registers modules to a new amplify instance:

amplify.register(new m.constructor());
}
});
// Associate new module instances with this amplify
modules.forEach(m => {
amplify.register(new m.constructor());

This PR reverts:

  1. 167c787
  2. (Partially) fd830eb

For validation, I ran production builds of Next.js, CRA, & Angular (https://github.com/aws-amplify/amplify-js-samples-staging/pull/166).


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@ericclemmons ericclemmons added SSR Issues related to Server Side Rendering bug Something isn't working Core Related to core Amplify issues labels Sep 21, 2020
@ericclemmons ericclemmons self-assigned this Sep 21, 2020
Comment on lines -66 to +76
if (JS.isEmpty(config)) return this._config;
if (isEmpty(config)) return this._config;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JS is @deprecated, so I fixed it while I was here.

@lgtm-com
Copy link

lgtm-com bot commented Sep 21, 2020

This pull request introduces 1 alert when merging db83aad into 26ce5df - view on LGTM.com

new alerts:

  • 1 for Unused variable, import, function or class

@lgtm-com
Copy link

lgtm-com bot commented Sep 21, 2020

This pull request introduces 2 alerts when merging dfa2114 into 26ce5df - view on LGTM.com

new alerts:

  • 2 for Unused variable, import, function or class

import NotificationClass from './PushNotification';

const _instance = new NotificationClass(null);
const PushNotification = _instance;
Amplify.register(PushNotification);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still needed though, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is, but this was hoisted into Pushnotification.ts' constructor.

Co-authored-by: Alex Hinson <alexmhinson@gmail.com>
@ericclemmons
Copy link
Contributor Author

Hmmm, I've published to Verdaccio (https://github.com/aws-amplify/amplify-js/blob/main/CONTRIBUTING.md#verdaccio), but now ng build --prod fails with this:

❯ yarn build
yarn run v1.22.4
$ ng build

ERROR in node_modules/@aws-amplify/ui-angular/dist/amplify-module.d.ts:1:22 - error NG6002: Appears in the NgModule.imports of AppModule, but could not be resolved to an NgModule class.

This likely means that the library (@aws-amplify/ui-angular) which declares AmplifyUIAngularModule has not been processed correctly by ngcc, or is not compatible with Angular Ivy. Check if a newer version of the library is available, and update if so. Also consider checking with the library's authors to see if the library is expected to be compatible with Ivy.

1 export declare class AmplifyUIAngularModule {
                       ~~~~~~~~~~~~~~~~~~~~~~

error Command failed with exit code 1.

I may test with https://docs.amplify.aws/start/q/integration/angular instead of https://github.com/aws-amplify/amplify-js-samples-staging/pull/166...

@lgtm-com
Copy link

lgtm-com bot commented Sep 21, 2020

This pull request introduces 2 alerts when merging 1300192 into 26ce5df - view on LGTM.com

new alerts:

  • 2 for Unused variable, import, function or class

@Amplifiyer
Copy link
Contributor

Changes look good to me, just for my understanding, how does Amplify.register() gets called in server/node context?

@ericclemmons
Copy link
Contributor Author

@Amplifiyer I ninja-edited the description above:

withSSRContext explicitly registers modules to a new amplify instance:

amplify.register(new m.constructor());
}
});
// Associate new module instances with this amplify
modules.forEach(m => {
amplify.register(new m.constructor());

Copy link
Contributor

@wlee221 wlee221 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM, thanks @ericclemmons. This is also for my understanding -- now that we’re registering modules if browserOrNode().isBrowser is true, how do modules get registered for react native? Still trying to wrap my head around RN flows with Amplify :p

@lgtm-com
Copy link

lgtm-com bot commented Sep 21, 2020

This pull request introduces 1 alert when merging ed5cf13 into 26ce5df - view on LGTM.com

new alerts:

  • 1 for Unused variable, import, function or class

@ericclemmons
Copy link
Contributor Author

@wlee221 I'll test RN & Gatsby tomorrow.

I'm wondering the same thing 🤔

I forgot our integration tests run on main, not in PRs, so I'm not comfortable merging and potentially getting surprised!

@lgtm-com
Copy link

lgtm-com bot commented Sep 22, 2020

This pull request introduces 1 alert when merging 5f2e531 into 26ce5df - view on LGTM.com

new alerts:

  • 1 for Unused variable, import, function or class

@ericclemmons
Copy link
Contributor Author

@amhinson I'll need to change my logic to if (!browserOrNode().isNode). In React Native, browserOrNode returns:

Screen Shot 2020-09-22 at 10 06 37 AM

Otherwise, we would need if (isBrowser || isReactNative) where isReactNative comes from:

typeof navigator != 'undefined' && navigator.product == 'ReactNative')

@ericclemmons
Copy link
Contributor Author

Going through tests now. Turns out our Jest environment is returning { isBrowser: true, isNode: true } 🤦

@ericclemmons
Copy link
Contributor Author

ericclemmons commented Sep 23, 2020

Simple steps for fixing Angular amplify bundling behavior:

  • Explicitly list sideEffects to where Amplify.register happens:

     "sideEffects": [
         "dist/aws-amplify-auth.js",
         "lib/Auth.js",
         "lib-esm/Auth.js",
         "src/Auth.ts"
       ]
  • Test yarn build --prod output of CRA, Next.js, Vue, & Angular for bundle-size differences.

Proposed steps for "reverting" Amplify.register behavior:

  • Remove all if (...) checks around Amplify.register.

  • Audit what references are added to Amplify._components. In my testing, I saw this being a combination of categories, [Function], and undefined! This may be because some categories lack getModuleName, but I couldn't track it down.

  • Ensure that Amplify.register(category) overrides Amplify[category] so that there is only a single reference.

  • On the client (browser & React Native), console.warn if Amplify.register is called again for a pre-registered category.

    We don't want this behavior on the server, because it's expected that new instances of Auth will be created and registered repeatedly.

  • Ideally, _modules is used in favor of _components because pushing to _components on the server creates memory leaks! 96fc69b12ccf2428f65242eff045a36da8b612a9

The goal of this is to accomplish the following:

  • Prevent every call of withSSRContext on each request from pushing to Amplify._components, creating memory leaks.
  • Warn customers on the client when they register multiple versions of a category (e.g. Auth).
  • Simplify the Amplify.register usage to match pre-SSR implementation.
  • Move Amplify.register outside of module scope so that we honor sideEffects: false.

@ericclemmons
Copy link
Contributor Author

Going to go with the simpler sideEffects implementation with @manueliglesias .

@mordka
Copy link
Contributor

mordka commented Sep 24, 2020

@ericclemmons could you provide which PR to track and the rough bugfix release timeline? We are blocked by #6836 and don't know any workaround fix.

@sammartinez
Copy link
Contributor

@mordka We will provide a link to the PR once we have one, we are working on it as we speak to unblock yourself.

@github-actions
Copy link

This pull request has been automatically locked since there hasn't been any recent activity after it was closed. Please open a new issue for related bugs.

Looking for a help forum? We recommend joining the Amplify Community Discord server *-help channels or Discussions for those types of questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 25, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working Core Related to core Amplify issues SSR Issues related to Server Side Rendering
Projects
None yet
Development

Successfully merging this pull request may close these issues.

No Auth module registered in Amplify after Fix #6811 AmplifyClass not getting configured on production build
6 participants