quasarframework / quasar

Quasar Framework - Build high-performance VueJS user interfaces in record time
https://quasar.dev
MIT License
25.97k stars 3.52k forks source link

Unable to use AWS Amplify JS as Quasar App Plugin #2946

Closed heitorlessa closed 5 years ago

heitorlessa commented 5 years ago

Software version

Operating System        Darwin(16.7.0) - darwin/x64
NodeJs                          8.9.0

Global packages
  NPM                           5.6.0
  yarn                            1.7.0
  quasar-cli                  0.17.20
  vue-cli                       3.0.5

Any other software related to your bug: package.json in relation to amplify lib

    "aws-amplify": "^1.1.18",
    "aws-amplify-vue": "^0.2.5",

JsFiddle

What did you get as the error?

No error - Vue doesn't see this.$Amplify initialized

What were you expecting?

Able to access this.$Amplify

What steps did you take, to get the error?

  1. Installed Amplify library: npm i aws-amplify aws-amplify-vue
  2. Created a new Quasar App plugin as it requires Vue.use: quasar new plugin amplify
  3. Modified src/plugin/amplify.js to include what's Amplify asks with the exception of new Vue according to Quasar docs:
// import something here
import Amplify, * as AmplifyModules from 'aws-amplify'
import { AmplifyPlugin } from 'aws-amplify-vue'
import AwsExports from './aws-exports'
Amplify.configure(AwsExports)

// It's important that you instantiate the Vue instance after calling Vue.use!

// leave the export, even if you don't use it
export default ({ app, router, Vue }) => {
  // something to do
  Vue.use(AmplifyPlugin, AmplifyModules)
  new Vue(app)
}
  1. Modified App.vue to import Amplify components as per installation guide:
<template>
  <div id="q-app">
    <router-view/>
  </div>
</template>

<script>
import { components } from "aws-amplify-vue"; // eslint-disable-line
export default {
  name: 'App',
  components: {
    ...components
  }
}
</script>

<style>
</style>
  1. Tried to access Amplify JS utilities through **`this.$Amplifyin one of my Quasar pages as well as through$vm0`` and can't see it being defined

This process works on Vanilla Vue (no Quasar, no Nuxt) - However I'm new to Quasar so I'm almost sure I'm doing something wrong --- Any help is more than appreciated.

Thank you!

rstoenescu commented 5 years ago

Hi,

Cut the new Vue(app) from your app plugin. You're not writing a boot plugin so you're basically duplicating the Vue instance which can be very unpredictable and definitely something to avoid.

heitorlessa commented 5 years ago

Hello and thank you for taking the time to reply to this -- It was exactly this, all working now!

heitorlessa commented 5 years ago

Turns out that although I was able to access this.$Amplify correctly after making that change I can't seem to get the components registered to use within my Quasar pages :(

I continue to get the same issue as if the component wasn't registered no matter whether I register them at App.vue (as you normally would in vanilla Vue apps) or directly in my component (Login.vue) :

vue.runtime.esm.js?2b0e:587 [Vue warn]: Unknown custom element: <amplify-authenticator> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

found in

---> <Login> at src/pages/Login.vue
       <QPageContainer>
         <QLayout>
           <BaseLayout> at src/layouts/BaseLayout.vue
             <App> at src/App.vue
               <Root>

Essentially the "offender" is this:

App.vue

<script>
import { components } from "aws-amplify-vue"; // THIS should inject the amplify-authenticator and others I'm after

export default {
  name: 'App',
  components: {
    ...components
  }
}
</script>

Login.vue

<template>
<amplify-authenticator></amplify-authenticator>
</template>

Is there any other path I can follow to resolve/troubleshoot this other than fall back to UMD to get this to work?

Really appreciate the help here

smolinari commented 5 years ago

It's interesting that the component registration doesn't work. But, instead of trying to inject the components at root component level, have you tried to import the needed components in the components, where you actually need them? That might also be a better solution anyway.

Scott

heitorlessa commented 5 years ago

Yep, that was my second thought and that didn't work too :(

I tried directly on Login.vue but the issue was the same. I thought it was perhaps an issue with npm, recreated everything and it was the same.

smolinari commented 5 years ago

This is a little work, but could you get a codesandbox going showing what you have done/ are trying to do?

You can use this as a start. (remove what's on the index page). https://codesandbox.io/s/ox3z7x7466

Scott

rstoenescu commented 5 years ago

Hi,

This has nothing to do with Quasar but more with how Vue works. Registering a Vue component can be done in two ways:

  1. By filling in the components prop of the default export of a Vue file, which registers the component(s) for the respective's Vue file template only (which doesn't means this is recursive and so any component from this Vue file doesn't has the same components registered as your Vue file in which you declared them)
  2. By using Vue.component('name-of-component', ComponentObject). This registers the component globally, so it doesn't needs to be declared in each Vue file it is being used, as per point 1 above.

So, per your usage, Login.vue should look like:

<template>
  <amplify-authenticator></amplify-authenticator>
</template>

<script>
import { components } from "aws-amplify-vue"

export default {
   components: {
      ...components
   },
   // the rest of your declarations
}

If you did use it like this and it doesn't works, then verify what the components import from aws-amplify-vue contains... Are they really the components that you want to use? Does components import have valid syntax so Vue can interpret them? Is it really an Object which contains camel case keys and are the values for each key really Vue components?

heitorlessa commented 5 years ago

Hi Razvan and Scott - I deleted this entire project and recreated using the quasar plugin for Vue cli 3 and following the same installation process it works just fine —- I’m sticking with quasar-plugin approach for Vue CLI 3 as opposed to use quasar-cli for now.

Like I said earlier this works with a vanilla Vue project (Vue create or Vue init) - My guess is that something I don’t know happens when you inject components when using a project bootstrapped by quasar-cli — Maybe something odd on my setup or the order which I can’t reproduce in a plain Vue project.

Will post a Gist later next week in case others experience the same issue and are open to use the quasar-plugin instead.

Nevertheless I appreciate your very prompt responses and ideas so far

On Fri, 4 Jan 2019 at 19:44, Razvan Stoenescu notifications@github.com wrote:

Hi,

This has nothing to do with Quasar but more with how Vue works. Registering a Vue component can be done in two ways:

  1. By filling in the components prop of the default export of a Vue file, which registers the component(s) for the respective's Vue file template only (which doesn't means this is recursive and so any component from this Vue file doesn't has the same components registered as your Vue file in which you declared them)
  2. By using Vue.component('name-of-component', ComponentObject). This registers the component globally, so it doesn't needs to be declared in each Vue file it is being used, as per point 1 above.

So, per your usage, Login.vue should look like:



Scott
heitorlessa commented 5 years ago

Hi Scott - Thanks for the detailed instructions, you can consider this closed as I've got it all working in a fresh started project using quasar-plugin over the quasar-cli.

If that's any helpful, I did two things differently from your steps above however:

  1. On step 5, I had created a Quasar App Plugin (quasar new plugin) instead of a component
  2. I tried using a component from Amplify (<amplify-authenticator></amplify-authenticator>) and that's where it failed with unregistered component error message last not due to the import { components } piece

As it's all working I'll continue to learn more of Quasar and use it for a Live Coding Series I have ahead of me and I want to make sure people are aware of how great this framework is and how they can use both AWS Amplify + Quasar to get it all done much more quickly (i.e. Back-end, SignUp/SignIn, etc etc).

Gist I said I'd do: https://gist.github.com/heitorlessa/8999bd29ba20622798c7ebd68870810a

smolinari commented 5 years ago

On step 5, I had created a Quasar App Plugin (quasar new plugin) instead of a component

Oh. That was a slight mistake on my part. Naturally it should be a plugin. I've changed the text above.

Scott

nothingismagick commented 5 years ago

Well, I took a go at this, and found something interesting. I was able to get it to work by placing the following in /src/plugins/amplify.js

import Amplify, * as AmplifyModules from 'aws-amplify'
import AmplifyPlugin from 'aws-amplify-vue'
import AwsExports from './aws-exports'
import SignIn from 'aws-amplify-vue/src/components/authenticator/SignIn.vue'
import SignUp from 'aws-amplify-vue/src/components/authenticator/SignUp.vue'
import SignOut from 'aws-amplify-vue/src/components/authenticator/SignOut.vue'
import ConfirmSignUp from 'aws-amplify-vue/src/components/authenticator/ConfirmSignUp.vue'
import ConfirmSignIn from 'aws-amplify-vue/src/components/authenticator/ConfirmSignIn.vue'
import ForgotPassword from 'aws-amplify-vue/src/components/authenticator/ForgotPassword.vue'
import Authenticator from 'aws-amplify-vue/src/components/authenticator/Authenticator.vue'
import SetMfa from 'aws-amplify-vue/src/components/authenticator/SetMFA.vue'
import RequireNewPassword from 'aws-amplify-vue/src/components/authenticator/RequireNewPassword.vue'

Amplify.configure(AwsExports)

export default ({ Vue }) => {
  Vue.prototype.$Amplify = Amplify
  Vue.use(AmplifyPlugin, AmplifyModules)

  Vue.mixin({
    components: {
      amplifySignIn: SignIn,
      amplifySignUp: SignUp,
      amplifySignOut: SignOut,
      amplifyConfirmSignUp: ConfirmSignUp,
      amplifyConfirmSignIn: ConfirmSignIn,
      amplifyForgotPassword: ForgotPassword,
      amplifyAuthenticator: Authenticator,
      amplifySetMfa: SetMfa,
      amplifyRequireNewPassword: RequireNewPassword
    }
  })
}

Then I was able to construct the SignIn box like this in /src/pages/index.vue:

    <amplify-authenticator></amplify-authenticator>

screen shot 2019-01-11 at 13 38 03

The mixin makes it available everywhere (the so-called "global mixin" approach) This seemed to be important too:

Vue.prototype.$Amplify = Amplify

mfreeman451 commented 5 years ago

I have this working with the quasar CLI and everything was pretty easy, straight forward. Didn't have to add all that junk in my amplify.js either.

somanypuppies commented 5 years ago

vue.runtime.esm.js?2b0e:587 [Vue warn]: Unknown custom element: <amplify-authenticator> - did you register the component correctly? For recursive components, make sure to provide the "name" option. I had the same issue when trying to add Amplify into an existing Vue project (worked fine with a fresh project).

In my case, it turned out to be a simple mistake. I just had to delete the previous yarn.lock file and re-run yarn install. Then Amplify started working in the existing project.

morgler commented 5 years ago

The only solution from all above that worked for me, was the one by @nothingismagick . But adding all this stuff manually to the amplify plugin seems like a fragile workaround. Is there any chance this will be fixed in the near future?

nothingismagick commented 5 years ago

It is super fragile - but I am pretty sure it is on the Amplify component end. It shouldn't be necessary to import like that (although on a side note this is exactly how to use Element-UI).

I am not sure how to "fix" this on our end.

On a side note, we will be publishing a four-part tutorial about integrating Amplify into Quasar 1.0. When we've published I'll be posting the link here.

nothingismagick commented 5 years ago

Link to the Tutorial https://medium.com/quasar-framework/creating-a-quasar-framework-application-with-aws-amplify-services-part-1-4-9a795f38e16d

MonrealRyan commented 2 years ago

Link to the Tutorial https://medium.com/quasar-framework/creating-a-quasar-framework-application-with-aws-amplify-services-part-1-4-9a795f38e16d

@nothingismagick is there an updated tutorial on this, for quasar v2? thanks.