About `Missing ref owner contextMissing ref owner context`
Version
3.1.1
Reproduction link
https://github.com/qmhc/vue-test
我在项目里定义了一个 Test
组件,这个组件有一定程度的 ref 嵌套引用:
<!-- Test.vue -->
<template>
<Test2 ref="select" class="test" @on-toggle="click">
<template #control>
<input :value="currentValue" />
</template>
<slot>
<Test4 ref="test4" class="test-tel"></Test4>
</slot>
</Test2>
</template>
<!-- Test2.vue -->
<template>
<div ref="wrapper" class="test2">
<div ref="reference">
<slot name="control">
<Test4></Test4>
</slot>
</div>
</div>
</template>
如果我直接在该项目中使用该组件,并不会产生任何问题,打包后应用可以正常使用;
当我将 Test
组件单独打包成插件后,在另一个项目安装并使用时:
在开发服务下会抛出警告:
[Vue warn]: Missing ref owner context. ref cannot be used on hoisted vnodes. A vnode with ref must be created inside the render function.
打包后会直接抛出错误:Uncaught TypeError: Cannot read property 'refs' of null
Steps to reproduce
在原始的项目里,运行 yarn run dev
能正常使用。
运行 yarn run build
打包 Test
组件后,用 vite
的模版创建一个新的项目,link 引用原始项目打包的组件,随后运行 yarn run dev
后得到标题中的警告,在这个项目打包后,页面不能正常打开。
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<!-- take warning -->
<Test></Test>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { Test } from 'test'
export default defineComponent({
name: 'App',
components: {
Test
}
})
</script>
What is expected?
同样的组件,两个使用场景出现了差异
What is actually happening?
同样的组件,两个使用场景出现了差异
你打包的时候有没有 externalize Vue?这个错误大概率是因为你的组件连 Vue 一起打包了进去导致两份 Vue 冲突。 另外,重现的依赖 link 了你本地磁盘的上的文件夹,也没有写清楚如何复现,信息不完整。
@yyx990803 谢谢回复。
我的失误。
我发现这个问题原始项目是添加了 external: ['vue']
的,测试库忘记添加,现在已加上,并已移除本地的 link。
运行 yarn run build 打包 Test 组件后,用 vite 的模版创建一个新的项目,link 引用原始项目打包的组件,随后运行 yarn run dev 后得到标题中的警告,在这个项目打包后,页面不能正常打开。
可能是我表达不清晰,在 测试库 打包后,使用 yarn create @vitejs/app test-project --template vue-ts
新建一个新的模版应用,通过 link 引用测试库打包的组件,并在 App.vue
(其他组件也可)中使用,然后 yarn run build
打包模版应用,yarn run serve
进行预览,可以得到相关错误。
因为模版应用是直接通过命令创建,并且除了引用测试组件外无其他修改,所以我没有 push 到线上。
在测试库添加了 external: ['vue']
后,在模版应用的开发模式 yarn run dev
下不会再出现警告了,但是打包构建后仍存在错误。
补充:
yarn 版本:v2.4+ node 版本:v16+ 操作系统:Windows10 Vite 版本:2.3.7 (原始发现是在 2.3.3)
@yyx990803 我发现这个问题似乎是和 link 协议有关,并不是 vue 本身的问题,在 serve 模式下 esbuild 可以准确追踪到 link 协议的文件夹,但是在 build 模式下 rollup 似乎没办法追踪 link 协议关联的包。然而我不确定这个问题是出在 vite 或是 rollup 上面,所以我仅报告这个问题。如果你觉得这个问题可能与 vite 有关,你可以考虑是否要迁移这个 issue。
@qmhc 我刚刚解决了这个问题,我修改了两个地方。1.rollup.config 中增加 resolve: { dedupe: ['vue'] } (这个是从vite,尤大回复别人的一个问题) 2.把vue从dependencies 改为 devDependencies 。不知道是哪个起作用了,但是确实解决了
@xsdream 你提醒了我,我想起我之前在 monorepo 下两个子应用包同时引用全局 store 包时会发生 store 被初始化两次(被解析成两个包),需要使用 resolve.dedupe
选项解决。
这个问题估计是由于 link 协议会让 vite 重新解析依赖,导致打包了多份 vue 而导致的错误,通过 resolve.dedupe
显式指定 vue 为同一副本。至于第二点应该是没有影响的。
@qmhc 我刚刚解决了这个问题,我修改了两个地方。1.rollup.config 中增加 resolve: { dedupe: ['vue'] } (这个是从vite,尤大回复别人的一个问题) 2.把vue从dependencies 改为 devDependencies 。不知道是哪个起作用了,但是确实解决了
我遇到了相同的问题,在 vite.config.ts 中增加 resolve: { dedupe: ['vue'] }
这个配置解决了,感谢!
我也遇到了这个问题,根据以上你们讨论的方法...并没有解决!
我开发了一个组件发布到npm 用vite创建的vue项目,使用一切正常 用vue-cli (webpack)创建的项目,就一直报楼主的错误,ref拿不到,onMounted应该包含在setup中。
我已搞得心力交瘁
我也遇到了这个问题,根据以上你们讨论的方法...并没有解决!
我开发了一个组件发布到npm 用vite创建的vue项目,使用一切正常 用vue-cli (webpack)创建的项目,就一直报楼主的错误,ref拿不到,onMounted应该包含在setup中。
我已搞得心力交瘁
嘿,你猜怎么着,我解决了!
vite 库模式,不知为什么我设置了external: ['vue']
,resolve: { dedupe: ['vue'] }
。
但发布到npm时,还是会把当前项目的vue上传上去。
需要把package.json
‘dependencies’中的vue放到'devDependencies'里面去。
@qmhc 我刚刚解决了这个问题,我修改了两个地方。1.rollup.config 中增加 resolve: { dedupe: ['vue'] } (这个是从vite,尤大回复别人的一个问题) 2.把vue从dependencies 改为 devDependencies 。不知道是哪个起作用了,但是确实解决了
我遇到了相同的问题,在 vite.config.ts 中增加
resolve: { dedupe: ['vue'] }
这个配置解决了,感谢!
在 vite.config.ts 中增加 resolve: { dedupe: ['vue'] }
,我也加了这个就好了
new dependencies optimized: element-plus/es/components/tree/style/css, element-plus/es/components/pagination/style/css 17:53:59 [vite] ✨ optimized dependencies changed. reloading