vue-demi
vue-demi copied to clipboard
TypeError: o.resolveComponent is not a function & 能否提供一个打包 vue2、vue3 组件库的 demo
我想打包一个 vue2、vue3 都可用的组件库 打包完后的组件,在 vue3 项目中使用没有问题 但是在 vue2 项目中运行时报了如下错误
Uncaught TypeError: e.defineComponent is not a function
at eval (index.js?dead:6)
at eval (index.js?dead:6)
at eval (index.js?dead:6)
at Object.../../long-bridge/fe-toolbox/packages/vue3-components/lib/LbNoticeBar/index.js (app.js:937)
at __webpack_require__ (app.js:849)
at fn (app.js:151)
at eval (cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/App.vue?vue&type=script&lang=js&:4)
at Module../node_modules/cache-loader/dist/cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/App.vue?vue&type=script&lang=js& (app.js:960)
at __webpack_require__ (app.js:849)
at fn (app.js:151)
当我修改打包命令 vue-demi-switch 2 && yarn build
打包后
Uncaught TypeError: o.withScopeId is not a function
at eval (index.js?dead:6)
at eval (index.js?dead:6)
at eval (index.js?dead:6)
at Object.../../long-bridge/fe-toolbox/packages/vue3-components/lib/LbNoticeBar/index.js (app.js:937)
at __webpack_require__ (app.js:849)
at fn (app.js:151)
at eval (cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/App.vue?vue&type=script&lang=js&:4)
at Module../node_modules/cache-loader/dist/cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/App.vue?vue&type=script&lang=js& (app.js:960)
at __webpack_require__ (app.js:849)
at fn (app.js:151)
这是我其中的一个组件 Icon 组件
<template>
<svg class="icon iconfont" aria-hidden="true" @click="e => $emit('click', e)">
<use :xlink:href="`#icon-${name}`"></use>
</svg>
</template>
<script>
import { defineComponent } from 'vue-demi'
export default defineComponent({
name: 'LbIcon',
props: {
/**
* isRequired.
*/
name: {
type: String,
required: true
}
}
})
</script>
<style lang="scss" scoped>
.icon {
width: 1em;
height: 1em;
overflow: hidden;
vertical-align: -0.15em;
cursor: pointer;
fill: currentColor;
}
</style>
这是打包后的代码
/*!
* @lb-public/vue3-components v0.5.0 Mon Jul 26 2021 19:07:24 GMT+0800 (中国标准时间)
* (c) 2021 @lbf2e.
* Released under the MIT License.
*/
!(function (e, n) {
'object' == typeof exports && 'undefined' != typeof module
? (module.exports = n(require('vue-demi'), require('vue')))
: 'function' == typeof define && define.amd
? define(['vue-demi', 'vue'], n)
: ((e = 'undefined' != typeof globalThis ? globalThis : e || self).index = n(e.VueDemi, e.Vue))
})(this, function (e, n) {
'use strict'
const i = e.defineComponent({ name: 'LbIcon', props: { name: { type: String, required: !0 } } }),
o = n.withScopeId('data-v-7a1e4f22')(
(e, i, o, t, d, r) => (
n.openBlock(),
n.createBlock(
'svg',
{ class: 'icon iconfont', 'aria-hidden': 'true', onClick: i[1] || (i[1] = n => e.$emit('click', n)) },
[n.createVNode('use', { 'xlink:href': `#icon-${e.name}` }, null, 8, ['xlink:href'])]
)
)
)
return (i.render = o), (i.__scopeId = 'data-v-7a1e4f22'), i
})
我想打包一个 vue2、vue3 都可用的组件库 打包完后的组件,在 vue3 项目中使用没有问题 但是在 vue2 项目中运行时报了如下错误
Uncaught TypeError: e.defineComponent is not a function at eval (index.js?dead:6) at eval (index.js?dead:6) at eval (index.js?dead:6) at Object.../../long-bridge/fe-toolbox/packages/vue3-components/lib/LbNoticeBar/index.js (app.js:937) at __webpack_require__ (app.js:849) at fn (app.js:151) at eval (cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/App.vue?vue&type=script&lang=js&:4) at Module../node_modules/cache-loader/dist/cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/App.vue?vue&type=script&lang=js& (app.js:960) at __webpack_require__ (app.js:849) at fn (app.js:151)
当我修改打包命令
vue-demi-switch 2 && yarn build
打包后Uncaught TypeError: o.withScopeId is not a function at eval (index.js?dead:6) at eval (index.js?dead:6) at eval (index.js?dead:6) at Object.../../long-bridge/fe-toolbox/packages/vue3-components/lib/LbNoticeBar/index.js (app.js:937) at __webpack_require__ (app.js:849) at fn (app.js:151) at eval (cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/App.vue?vue&type=script&lang=js&:4) at Module../node_modules/cache-loader/dist/cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/App.vue?vue&type=script&lang=js& (app.js:960) at __webpack_require__ (app.js:849) at fn (app.js:151)
这是我其中的一个组件 Icon 组件
<template> <svg class="icon iconfont" aria-hidden="true" @click="e => $emit('click', e)"> <use :xlink:href="`#icon-${name}`"></use> </svg> </template> <script> import { defineComponent } from 'vue-demi' export default defineComponent({ name: 'LbIcon', props: { /** * isRequired. */ name: { type: String, required: true } } }) </script> <style lang="scss" scoped> .icon { width: 1em; height: 1em; overflow: hidden; vertical-align: -0.15em; cursor: pointer; fill: currentColor; } </style>
这是打包后的代码
/*! * @lb-public/vue3-components v0.5.0 Mon Jul 26 2021 19:07:24 GMT+0800 (中国标准时间) * (c) 2021 @lbf2e. * Released under the MIT License. */ !(function (e, n) { 'object' == typeof exports && 'undefined' != typeof module ? (module.exports = n(require('vue-demi'), require('vue'))) : 'function' == typeof define && define.amd ? define(['vue-demi', 'vue'], n) : ((e = 'undefined' != typeof globalThis ? globalThis : e || self).index = n(e.VueDemi, e.Vue)) })(this, function (e, n) { 'use strict' const i = e.defineComponent({ name: 'LbIcon', props: { name: { type: String, required: !0 } } }), o = n.withScopeId('data-v-7a1e4f22')( (e, i, o, t, d, r) => ( n.openBlock(), n.createBlock( 'svg', { class: 'icon iconfont', 'aria-hidden': 'true', onClick: i[1] || (i[1] = n => e.$emit('click', n)) }, [n.createVNode('use', { 'xlink:href': `#icon-${e.name}` }, null, 8, ['xlink:href'])] ) ) ) return (i.render = o), (i.__scopeId = 'data-v-7a1e4f22'), i })
Have you solved it
vue3-sketch-ruler contain template compile demo with vue-demi to vue2/3
我想打包一个 vue2、vue3 都可用的组件库 打包完后的组件,在 vue3 项目中使用没有问题 但是在 vue2 项目中运行时报了如下错误
Uncaught TypeError: e.defineComponent is not a function at eval (index.js?dead:6) at eval (index.js?dead:6) at eval (index.js?dead:6) at Object.../../long-bridge/fe-toolbox/packages/vue3-components/lib/LbNoticeBar/index.js (app.js:937) at __webpack_require__ (app.js:849) at fn (app.js:151) at eval (cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/App.vue?vue&type=script&lang=js&:4) at Module../node_modules/cache-loader/dist/cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/App.vue?vue&type=script&lang=js& (app.js:960) at __webpack_require__ (app.js:849) at fn (app.js:151)
当我修改打包命令
vue-demi-switch 2 && yarn build
打包后Uncaught TypeError: o.withScopeId is not a function at eval (index.js?dead:6) at eval (index.js?dead:6) at eval (index.js?dead:6) at Object.../../long-bridge/fe-toolbox/packages/vue3-components/lib/LbNoticeBar/index.js (app.js:937) at __webpack_require__ (app.js:849) at fn (app.js:151) at eval (cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/App.vue?vue&type=script&lang=js&:4) at Module../node_modules/cache-loader/dist/cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/App.vue?vue&type=script&lang=js& (app.js:960) at __webpack_require__ (app.js:849) at fn (app.js:151)
这是我其中的一个组件 Icon 组件
<template> <svg class="icon iconfont" aria-hidden="true" @click="e => $emit('click', e)"> <use :xlink:href="`#icon-${name}`"></use> </svg> </template> <script> import { defineComponent } from 'vue-demi' export default defineComponent({ name: 'LbIcon', props: { /** * isRequired. */ name: { type: String, required: true } } }) </script> <style lang="scss" scoped> .icon { width: 1em; height: 1em; overflow: hidden; vertical-align: -0.15em; cursor: pointer; fill: currentColor; } </style>
这是打包后的代码
/*! * @lb-public/vue3-components v0.5.0 Mon Jul 26 2021 19:07:24 GMT+0800 (中国标准时间) * (c) 2021 @lbf2e. * Released under the MIT License. */ !(function (e, n) { 'object' == typeof exports && 'undefined' != typeof module ? (module.exports = n(require('vue-demi'), require('vue'))) : 'function' == typeof define && define.amd ? define(['vue-demi', 'vue'], n) : ((e = 'undefined' != typeof globalThis ? globalThis : e || self).index = n(e.VueDemi, e.Vue)) })(this, function (e, n) { 'use strict' const i = e.defineComponent({ name: 'LbIcon', props: { name: { type: String, required: !0 } } }), o = n.withScopeId('data-v-7a1e4f22')( (e, i, o, t, d, r) => ( n.openBlock(), n.createBlock( 'svg', { class: 'icon iconfont', 'aria-hidden': 'true', onClick: i[1] || (i[1] = n => e.$emit('click', n)) }, [n.createVNode('use', { 'xlink:href': `#icon-${e.name}` }, null, 8, ['xlink:href'])] ) ) ) return (i.render = o), (i.__scopeId = 'data-v-7a1e4f22'), i })
Have you solved it
理论上是没法同时兼容vue2、vue3 但是可以做到一份代码分别打出vue2版本的包、与vue3版本的包
可以使用rollup实现
- 使用vue-demi开发
- rollup.config.js 自定义插件resolveId, vue2的vue-demi 指向vue2版本,vue3的vue-demi 指向vue3版本
- 同时要兼容 rollup-import-vue,vue2 的编译使用:https://github.com/KesionX/rollup-plugin-vue-2 vue3的编译使用:https://github.com/vuejs/rollup-plugin-vue
eg: 提供一个不算完整的rollup.config.js ,但能够表达我的意思
import commonjs from 'rollup-plugin-commonjs'
import vue_2 from "rollup-plugin-ue2";
import vue_3 from "rollup-plugin-vue";
function vueTransformPlugin(isVue2){
return {
resolveId (source) {
if (/vue-demi/.test(source)) {
if (isVue2) {
return "./node_modules/vue-demi/lib/v2/index.mjs";
} else {
return "./node_modules/vue-demi/lib/v3/index.mjs";
}
}
}
}
}
/**
* returns {import ('rollup' ).RollupOptions}
*/
function getBaseConfig(isVue2){
const vueConfig = {
css: true,
style: {
preprocessOptions:{
less: {
javascriptEnabled: true,
}
}
}
}
const vueComplier = isVue2 ? vue_2(vueConfig) : vue_3(vueConfig);
return {
external:[
/@vue\/composition-api/,
...Object.keys (dependencies| {}),
... Object. keys (peerDependencies| {}),
],
input: "./src/index.ts",
output: {
dir: `dist/${isVue2 ? "u2" : "'u3"}`,
format: "esm",
globals: { vue: "Vue" },
},
plugins: [
commonjs(),
vueComplier,
vueTransformPlugin(isVue2)
]
}
}
const config_ue2 = getBaseConfig(true);
const config_ue3 = getBaseConfig(false);
export default [config_ue2, config_ue3];
如果只使用 jsx 的 render ,不使用template语法可以吗
有示例吗,跑不起来
This library is only compatible with the public API, the vnode-related API is not adapted. It is recommended to use template
or JSX with different versions of Vite plugin to generate two versions of the bundle file.
本库仅抹平了公开 API,vnode 相关的 API 并没有做适配。建议使用 template 或 JSX并配合不同版本 Vite plugin 生成两个版本的打包文件。