Skip to content

Create vue query plugin #112

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

Closed
wants to merge 2 commits into from

Conversation

aantipov
Copy link
Contributor

Story

I wanted to use VueQuery in my app's root component:

useQueryProvider();
useBookQuery(bookId);

But I got an error in the console saying that there are no query client available.

After digging into it, I realised that useQueryProvider calls Vue's provide. Query hooks rely on inject which can be used in child components only. That's why I got the error

Problem

I could work around - e.g. create a wrapper root component and call useQueryProvider there. Or refactor my root component and call query hooks in children components.

But I see also other problems with useQueryProvider:

  • it's not clear why I should initialize a library using a useQueryProvider hook. Should I use it in every component or only in the root component?
  • why "Provider"? "Provider" - is a common term in React community because of React's Context. In Vue community "Provider" doesn't really makes any sense.

Vue libraries are usually initialized as plugins.
Take for example Pinia
image

I think we can do the same thing - initialize Vue Query as a plugin and, thus, make it consistent with other Vue libraries.

It also fits perfectly our case. In 99% cases our users need a global Query Client. We can make it globally available when initializing as a plugin. That would solve my original problem - using VueQuery in the root component.

Implemented Changes

  • created VueQueryPlugin (to be used in Vue3 only because plugin api in Vue2 and Vue3 is different)
  • added tests
  • updated docs - wrote a section on how to init VueQuery

With these changes Vue3 users are able to init VueQuery like this:
image

@vercel
Copy link

vercel bot commented Jan 19, 2022

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/damianosipiuk/vue-query/HjBVg9R8fa8N79rQypJEtcNg98Pm
✅ Preview: https://vue-query-git-fork-aantipov-create-vue-que-061ab0-damianosipiuk.vercel.app

@codesandbox-ci
Copy link

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 246d485:

Sandbox Source
DamianOsipiuk/vue-query: basic Configuration
DamianOsipiuk/vue-query Configuration
DamianOsipiuk/vue-query: nuxt-simple Configuration

@sonarqubecloud
Copy link

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
0.0% 0.0% Duplication

@codecov
Copy link

codecov bot commented Jan 19, 2022

Codecov Report

Merging #112 (246d485) into main (1f74353) will not change coverage.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff            @@
##              main      #112   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           13        14    +1     
  Lines          240       252   +12     
  Branches        45        50    +5     
=========================================
+ Hits           240       252   +12     
Impacted Files Coverage Δ
src/vue/vueQueryPlugin.ts 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 1f74353...246d485. Read the comment docs.

@DamianOsipiuk
Copy link
Owner

@aantipov Hi,
I specifically avoided creating a plugin, cause I wanted to create one that works for both Vue 2 and Vue 3.
So far what i explored was that both versions could call install method but provide was missing there.
I wanted to simulate the same behavior as provide, but didn't have time to actually deep dive into it's code.

Currently i think we could borrow a piece of code from pinia which potentially should work: https://github.com/vuejs/pinia/blob/v2/packages/pinia/src/vue2-plugin.ts#L36-L45

Also if we would be able to create a single plugin that works for both versions, i would be happy to mark useQueryProvider as deprecated.

@aantipov
Copy link
Contributor Author

Also if we would be able to create a single plugin that works for both versions, i would be happy to mark useQueryProvider as deprecated.

That would be ideal.

On the other hand, I'm asking myself - how far should we go in Vue2 support? There is also another dimension - NuxtJS (current with Vue2 and future with Vue3 versions) which can also bring certain complexities.

@DamianOsipiuk what expectation do you have regarding the usage of VueQuery within Vue2 and Vue3 ecosystems?

Vue3 is 1.5 years old. Smaller projects are migrating to Vue3. Bigger projects will, probably, never migrate to Vue3. And I don't even expect those bigger projects start using CompositionAPI (it has its own limitations).

VueQuery requires a mind shift as of handling server data. Old big Vue2 projects most probably won't risk that change.

There are already many apps created with Vue3. And, going forward, Vue3 base will increase and Vue2's will decrease

I, personally, woudn't event consider supporting legacy Vue2. Better invest time into DX and Documentation to make the library more attractive, understandable and easier to work with.

What's your opinion?

@DamianOsipiuk
Copy link
Owner

DamianOsipiuk commented Jan 20, 2022

I think that we should support Vue 2 at least to the point when

  • its usage will drop to some insignificant number
  • maintenance will become very difficult
  • we would like to do some breaking changes that will be incompatible wit Vue 2

As of now Vue 2 usage is still very big. Vue 2 is set as the latest tag on npm which can cause new projects to still use it.
Also big projects despite being hard to migrate to Vue 3, can still gradually migrate from Vuex and replace parts of it with vue-query.
I have personally worked on a very big project using Vue 2, where compositionAPI was introduced and migration to proper server cache solution was considered.

Support for Vue 2 is currently pretty straightforward (maybe besides devtools), so i think we can still easily support it.

Also there is Vue 2.7 in the pipeline that should enable compositionAPI usage without additional libraries. This should make support even easier.

@aantipov
Copy link
Contributor Author

Also there is Vue 2.7 in the pipeline that should enable compositionAPI usage without additional libraries. This should make support even easier.

Oh, didn't know about it. So it'll make vue-demi redundant?

Ok. Understand your point. Fair enough.

Currently i think we could borrow a piece of code from pinia which potentially should work: https://github.com/vuejs/pinia/blob/v2/packages/pinia/src/vue2-plugin.ts#L36-L45

This hack looks really cryptic, I don't like it and don't know how it works and if it can help us.
I would avoid using something like this.

I have another idea.
What we need is a global storage for QueryClients and being able to initialise it using app.use right?
The alternative to provide/inject is Vue.prototype in Vue2 and config.globalProperties in Vue3 https://v3.vuejs.org/guide/migration/global-api.html#vue-prototype-replaced-by-config-globalproperties.
I think we can use either during plugin initialization. But that would require more changes. Also that might break existing integrations.

My proposal is to go with the current app.use(VueQueryPlugin) for Vue3.
And, if we really want to make the plugin work for Vue2, look into the config.globalProperties solution instead of provide/inject

@DamianOsipiuk
Copy link
Owner

I would like to stick with provide/inject as it is recommended way to pass data context-like in Vue 3.
I enhanced your PR with Vue 2 plugin logic. I think it's not that bad. #116
Test are commented for now.
There are some more changes to be done. Also verifying if you can properly use multiple plugins with different keys for clients.

@aantipov
Copy link
Contributor Author

aantipov commented Jan 21, 2022

I enhanced your PR with Vue 2 plugin logic. I think it's not that bad

Agree. Thanks. Hope it all works as expected. Looking forward to the feature!

Also verifying if you can properly use multiple plugins with different keys for clients.

Good point. It might be helpful to have this opportunity

@DamianOsipiuk
Copy link
Owner

Closing in favor of #116

@aantipov aantipov deleted the create-vue-query-plugin branch January 23, 2022 09:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants