-
-
Notifications
You must be signed in to change notification settings - Fork 158
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
Vue3 lib not working in Vue2 projects #152
Comments
@antfu do you maybe have any pointers on where the issue may be? Don't want to ping you unnecessarily but I'm kinda lost at this point 😅 |
@LinusBorg answered me on Discord saying the following: As said, might be useful to have in the |
It might not be correct that "vue-demi is not for vue2/3 component", you can use render function to make the component work for both vue2/3. import {h,defineComponent} from 'vue-demi'
export default defineComponent({
//...
render(){
return h('div', 'hello')
}
}) In your situation, your component is a sfc, and sfc need compiler to complie to js, where vue-demi doesn't involve in, also there are gap between compiler of vue2/3, that's the reason why the lib you built don't work in vue2. My work around is build two dist separately for vue2/3, here is the template repo, hope it will help. |
I spent some time with vue-demi to make a tiny vue component library and managed to make it compatiblie with both vue 2 and 3 by manually fixing the build result, which is not ideal. It seems like when building the library to production via vite(rollup), the bundler is replacing "vue-demi" that I wrote in my component file(.ts) with "vue", and removing isVue2 conditional statements, which, to me, is not understandable. Initially I wrote my component library w/ render function(h) like you mentioned @KaygNas , and compiled it with vite(rollup). I manually fixed the build files and managed to make it compatible w/ vue2 & 3
// /lib/my-component.es.js
import { defineComponent, ref, isVue2, /*...*/ } from "vue-demi"
//...
const vm = getCurrentInstance();
const h$1 = h.bind(vm);
if(isVue2) {
return h$1(/*compatible w/ vue2 syntax*/)
} else {
return h$1(/*compatible w/ vue3 syntax*/)
} When I write "vue-demi" inside my component directly (not in the build file), vite replaces it with "vue" during build.. And when I try to write the conditional statement directly inside my component(not in the build file), vite makes them go away and only leaves vue3-relative codes inside the resulting build file(this is probably because I initially setup my library project with vue 3). The simple example(use-mouse) vue-demi gives us seems like only utilizes tsc when building? which seems to be the reason why it works because the tsc doesn't try to replace "vue-demi". If there is a way to stop replacing "vue-demi" with "vue" and removing conditional statements such as the one i wrote above, i think this problem would be solved. |
Do you tell rollup that vue-demi is an external? Try it then rollup might keep the vue-demi import statement untouched. Check the docs here. |
This works woderfully! My lack of understanding of how rollup handles external dependencies seems to be the cause of the problem i encountered, apparently 🤦♂️ After adding vue-demi as an external in rollup option, everything works as I initially expected! I'll try to publish my library package to public npm registry & github maybe in this weekends to share further details of what I've done & leave a link to it's repo in this comment. To summarize what I've done w/ @KaygNas 's advise
// vue 2
h('div',
{ class: 'box', attrs: { id: 123 } },
'text inside div tag'
)
// vue 3
h('div',
{ class: 'box', id: 123 }, // flattened
'text inside div tag'
)
// how i did it.. doesn't seem ideal though but it surprisingly works
h('div',
{ class: 'box', id: 123, attrs: { id: 123 } }, // added attrs property from vue 2 syntax
'text inside div tag'
) look here to see the breaking change // vite.config.js
//...
rollupOptions: {
external: ['vue-demi'],
// ...
}
// ... But this begs another question that is there any reason why there's no mention in the doc about externalizing vue-demi in vite(or rollup) config file in the first place, since it seems like it's rollup's default behavior not to include 'vue-demi' namespace in build result if vue-demi is not specified as the external dependency. |
seems like there's already a better solution to the render function's compatibility issue.. |
I published a public repo & its npm package. |
forgot to actually externalizing "vue-demi" in the public package🤦♂️ |
First of all, I saw a couple of issues that involved more or less the same issue, but I tought it would be useful to group everything into one issue, so we could hopefully try to solve it.
Related issues:
Problem
I'm currently building a private reusable package for a real-world application. This application runs on
nuxt2
(currentlynuxt-bridge
), and we're planning to migrate tonuxt3
when all the packages we need are there. The idea was to build that reusable package invue3
, and usevue-demi
to make it possible to be used in ournuxt-bridge
app.At first I just tried building the library and use it in a separate vue 3 app. With Vite it was really fast & easy to make it work 🎉
However when I tried importing it in our
nuxt-bridge
app I came across several issues:When externalising
vue
dependency in vite, I got a list of warnings that some functions are not exported by vue. This is what the most issues are about.When I don't externalise
vue
invite.config.js
, I just get an empty component. In my repro I don't get any warning. I just see an anonymous component in my dev tools. In my production nuxt-app, I see the following error:no template or render function is defined
. The component seemed to be imported correctly, it just doesn't render any HTML.I saw in other issues that the solution might be to externalise
vue-demi
as well, but that doesn't seem to make any difference for this.also tried using
npx vue-demi-fix
&&npx vue-demi-switch 2
commands, but these also doesn't seem to be changing a whole lot.I also saw that in #117 , @koooge researched into the issue a bit and saw that it might be due to a breaking change in @vue/core.
That's when I decided to build a repro with a vue2 app (@vue/cli), vue3 app (vite) and a simple component in a separate lib.
Repro
https://github.com/jclaessens97/vue-demi-vue2-broken-repro
I hope we can look into this issue and try to come up with a solution to be able to make vue3 components compatible for vue2, until everything is vue3 ready.
The text was updated successfully, but these errors were encountered: