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

docs: added remark about component libraries #154

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

jclaessens97
Copy link

To avoid more issues about why a certain Vue3 library/plugin failed to work in a Vue2 project, I thought it would be useful to add it to the README.md.

I tried to add a more compact version of the answer @LinusBorg gave me on Discord (see #152).

@antfu
Copy link
Member

antfu commented Apr 19, 2022

I think the message is a bit misleading. The problem is not that you can't use vue-demi with a component library (e.g. @vueuse/components is using vue-demi, and if you going to ship Vue SFC you might still need vue-demi for the APIs), but the fact the SFC compilation process and the result are different across Vue 2 and 3.

Instead of You CAN'T, I think it's better to Be cautious to work with Vue SFC.

@dsvgl
Copy link

dsvgl commented Apr 19, 2022

In order to build a component library/plugin for both Vue2 and Vue3 you could either publish plain Vue files or build your library seperately for Vue2 and Vue3.

It would be nice, to have an example for exactly that: use components from Vue 3 inside a Vue 2 app. Maybe you could also add one to the example folder?

I struggle with this atm. As @antfu said, I think you still need vue-demi for the different APIs.
I think, I managed to do it by having a separate folder with dedicated package.json and and vite config to compile vue 3 components into a lib for vue 2. Feels messy. Maybe there is a cleaner way.

@jclaessens97
Copy link
Author

@antfu, you're right. I tried to rephrase it to make it more clear that it is still possible, but requires some extra steps.

@dsvgl, I currently don't have any examples on how to do any of the 2 options. My use case allows me to just compile it solely for vue 2 now, and recompile for vue 3 later when we upgrade to nuxt 3. But I do agree that it might be useful to have some basic example somewhere, altough it can get complex pretty quick I think.

@dsvgl
Copy link

dsvgl commented Apr 19, 2022

@jclaessens97 ok. I have the same use case :) Do you have a repo to look into? Or maybe we could have a chat on discord, so we don't pollute this PR? I'm Dominic#2461 over there. Would be highly appreciated! Of course, only if you want.

@casyalex
Copy link

@antfu I really think this should add to doc asap, since SFC are the most common practice in Vue project. It should clearify that this lib might not as mighty as they think.

@sadeghbarati
Copy link

sadeghbarati commented Sep 22, 2022

In order to build a component library/plugin for both Vue2 and Vue3 you could either publish plain Vue files or build your library separately for Vue2 and Vue3. Both options can be tricky because there are a few differences in their runtime APIs.

@antfu

@vueuse/components is using vue-demi

@vueuse/components is renderless components

https://github.com/sadeghbarati/vue-demi-component-reproductions
https://www.npmjs.com/package/@smooth-scrollbar-contrib/vue-test?activeTab=explore


  • in Vue 2.6 and maybe 2.7 component needs this.$listeners to events like ( @click, @... ) or CustomEvents works properly on components, but in Vue 3 $listeners merges into $attrs and thats requires build your library separately for Vue2 and Vue3 also postinstall script to switch between build code based on user Vue version

  • If you want create a Vue package with vue-demi you have to use APIs that exist in both Vue 2 & 3

  • Writing composable libs is easy with vue-demi but if you want to create Vue components that requires to check Vue 2 & 3 documentation and also migrations guides 😭


vuejs/vue#12690

Vue 2 render functions work very differently from Vue 3. This was the part that had the biggest changes in Vue 3. Please make sure to read the relevant documentation: https://v2.vuejs.org/v2/guide/render-function.html

This will add some extra complexity to library authors.

  • Vue 2.6 and 2.7 h function type is different from Vue 3 ( I know it's different from other versions of Vue, only mention cause This will adds some extra complexity to library authors )

for example Vue 2.6 and 2.7 ref types is ref?: string
but in Vue 3 is ref?: VNodeRef;



There are a lot of vue-demi packages on GitHub each of them use their own ways ( not recommended ways, Recommended ways that are not even mentioned in this project ), which cannot be recognized if they are doing the right thing or not 🤔


for example json-editor-vue use getCurrentInstance for access template ref onMount (IIRC Evan said don't use getCurrentInstance cause it's not safe and it's maybe move to a private or internal function in new releases)


vue-winbox use h-demi helper, but actually I prefer to use isVue3 or isVue2 for simple implementation

vue-swipe-modal


BTW took me two weeks or maybe more to test vue-demi with Vue 2.6.14 - 2.7.10 - 3.2.39 :[ to find out what is going on

@sadeghbarati
Copy link

sadeghbarati commented Sep 24, 2022

unplugin-auto-import vue preset

export const CommonCompositionAPI = [
  // lifecycle
  'onActivated',
  'onBeforeMount',
  'onBeforeUnmount',
  'onBeforeUpdate',
  'onErrorCaptured',
  'onDeactivated',
  'onMounted',
  'onServerPrefetch',
  'onUnmounted',
  'onUpdated',

  // setup helpers
  'useAttrs',
  'useSlots',

  // reactivity,
  'computed',
  'customRef',
  'isReadonly',
  'isRef',
  'markRaw',
  'reactive',
  'isReactive',
  'isProxy',
  'readonly',
  'ref',
  'shallowReactive',
  'shallowReadonly',
  'shallowRef',
  'triggerRef',
  'toRaw',
  'toRef',
  'toRefs',
  'unref',
  'watch',
  'watchEffect',
  'watchPostEffect',
  'watchSyncEffect',

  // component
  'defineComponent',
  'defineAsyncComponent',
  'getCurrentInstance',
  'h', // different types
  'inject',
  'nextTick',
  'provide',
  'useCssModule',
  'createApp',

  // effect scope
  'effectScope',
  'EffectScope',
  'getCurrentScope',
  'onScopeDispose',
]

These APIs can be used within your package without needing to use isVue2 or isVue3, except for some APIs with different types ( I think ) or breaking-changes APIs or APIs that has Limitations

If you can't handle the API with isVue conditions you have to separate your build code for example vue-demi lib folder
and also need scripts and bin

postinstall script (Run AFTER the package is installed.)
simple cli for manually switching between your build

Hope it helps someone and I Hope Anthony Correct the mistakes in my explanation

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.

5 participants