针对 Vue 2.6中使用 Composition API 的情况,在使用 Vue CLI 打包为 CommonJS 模式的库时,这个lib库也是vue2.6,并且也使用了Composition API,在客户端引入改lib库时,出现的错误如下
Error: [vue-composition-api] must call Vue.use(VueCompositionAPI) before using any function ...
1、客户端
-
1、main.js
import Vue from 'vue' import App from './App.vue' import VueCompositionAPI from '@vue/composition-api' Vue.use(VueCompositionAPI) new Vue({ render: (h) => h(App), }).$mount('#app') -
2、App.vue
<template> <div id="app"> <TestDisplay></TestDisplay> </div> </template> <script setup> // lib 测试库 import { TestDisplay } from 'zzz' </script> <style></style>
2、lib
-
1、组件TestDisplay
<template> <div>{{ test.text }}</div> </template> <script> import { reactive } from '@vue/composition-api' export default { setup() { const test = reactive({ text: 'xxxxxxxx' }) console.log('only for setup', test) return { test } }, } </script> -
2、vue.config.js
const { defineConfig } = require('@vue/cli-service') module.exports = defineConfig({ configureWebpack: { externals: { '@vue/composition-api': '@vue/composition-api', }, }, }) -
3、
"build": "vue-cli-service build --mode production --target lib src/index.js"
在启动客户端时,发现就会报上述那个错误,"Error: [vue-composition-api] must call Vue.use(VueCompositionAPI) before using any function."
我排查了下猜测是因为库文件和客户端使用的@vue/composition-api入口不一样导致这个问题的,客户端使用esm的@vue/composition-api,而lib库是通过vue.config.js(webpack)打包,但只支持使用commonjs
但是我把main.js 修改成const VueCompositionAPI = require("@vue/composition-api");,这样确实不会报Error: [vue-composition-api] must call Vue.use错误了
但是composition-api就会报另一个错误TypeError: Cannot read properties of undefined (reading 'text')"
3、尝试用vite构建了一个es的包
发现可以正常使用,则说明就是库文件和客户端使用的@vue/composition-api入口不一样导致这个问题的
import { defineConfig } from 'vite'
import { createVuePlugin } from 'vite-plugin-vue2'
import { resolve } from 'path'
export default defineConfig({
build: {
lib: {
entry: './src/index.js',
},
minify: false,
rollupOptions: {
external: ['@vue/composition-api'],
output: [
{
format: 'es',
dir: resolve(__dirname, './dist/es'),
},
],
},
},
plugins: [createVuePlugin(/* options */)],
})
4、解决方案
在客户端使用alias将@vue/composition-api,都统一成commonjs模块,就可以正常使用了
...
configureWebpack: {
resolve: {
alias: {
"@vue/composition-api": path.join(
__dirname,
"./node_modules/@vue/composition-api/index.js"
),
},
},
},
...