我用 rollup 打包了一个 vue3 组件,组件代码:
// main.vue
<template>
<div>
<div @click="clickDiv">{{ 1 }}</div>
<div ref="divRef"></div>
</div>
</template>
<script>
import { onMounted, ref, defineComponent } from 'vue'
export default defineComponent({
name: 'Vue3Component',
mounted () {
console.log('component mounted') // it works well
},
setup() {
const divRef = ref()
const clickDiv = () => {
console.log('divRef', divRef) // it causes some warnings
}
onMounted(() => {
console.log('component onMounted') // it causes some warnings
})
return {
a: ref(1),
clickDiv,
divRef
}
},
})
</script>
入口文件:
// index.js
import Vue3Component from './main.vue'
Vue3Component.install = (app) => {
app.component(Vue3Component.name, Vue3Component)
}
export {
Vue3Component
}
rollup 配置文件:
// rollup.config.js
import resolve from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import pkg from './package.json'
import external from 'rollup-plugin-peer-deps-external'
import vuePlugin from 'rollup-plugin-vue'
const extensions = ['.vue', '.js']
const globals = {
vue: 'Vue',
'highlight.js': 'hljs',
'marked': 'marked'
}
export default [
{
input: 'src/index.js',
output: [
{
name: 'VueNextMEditor',
file: pkg.main,
format: 'umd',
globals
},
{
file: pkg.module,
format: 'es'
},
{
name: 'VueNextMEditor',
file: pkg.unpkg,
format: 'umd',
plugins: [terser()],
globals
}
],
plugins: [
external(),
vuePlugin(),
resolve(),
commonjs({ extensions })
]
}
]
当我在组件根目录下用 vue-cli 生成了一个 example 项目调试这个组件时,我发现 setup
中的 onMounted
方法没有生效,产生了如下警告:
[Vue warn]: onMounted is called when there is no active component instance to be associated with. Lifecycle injection APIs can only be used during execution of setup(). If you are using async setup(), make sure to register lifecycle hooks before the first await statement.
ref
也产生了警告:
[Vue warn]: Missing ref owner context. ref cannot be used on hoisted vnodes. A vnode with ref must be created inside the render function.
at <Vue3Component>
at <App>
但是 setup
外面的 mounted
函数是可以正常执行的,就很奇怪。
不知道是我打包出现了问题还是组件引用产生了问题。项目完整地址:
项目地址
找到原因了。因为我在组件和example中安装了两个vue依赖。解决方法是我只在根目录下安装vue,然后在example中用 pnpm link ../node_modules/vue 就可以。