vue-demi 版本检测机制详解与antv-x6-vue-shape识别错误问题解析

2025年12月02日12 次阅读2 人喜欢
vuevue-demi@antv/x6-vue-shape版本检测依赖管理

vue-demi 版本检测机制详解与 @antv/x6-vue-shape 识别错误问题解析

概述

本文基于与 Kimi 的对话记录,详细解析 vue-demi 的版本检测机制,以及在 @antv/x6-vue-shape 中常见的识别错误问题及其解决方案。

vue-demi 版本检测机制

核心逻辑

vue-demi 的版本检测逻辑非常简单直接:在 postinstall 脚本中 require('vue') 读取本地实际安装的 vue 主包版本,然后根据版本号将 lib/index.* 指向对应的预置文件。

判断步骤

  1. 读取版本号require('vue') 获取真实版本号
  2. 版本分类判断
    • 如果版本以 3. 开头 → 指向 lib/v3/index.*exports.isVue3 = true / exports.isVue2 = false
    • 如果版本是 2.7.x → 指向 lib/v2.7/index.*exports.isVue2 = true / exports.isVue3 = false
    • 如果版本是 2.0 ~ 2.6 → 指向 lib/v2/index.*exports.isVue2 = true / exports.isVue3 = false,并自动安装 @vue/composition-api 作为 polyfill

关键代码片段

javascript 复制代码
// scripts/postinstall.js
const Vue = loadModule('vue')
if (!Vue || typeof Vue.version !== 'string') {
  console.warn('[vue-demi] Vue is not found.')
  return
}
if (Vue.version.startsWith('2.7.')) {
  switchVersion(2.7)
} else if (Vue.version.startsWith('2.')) {
  switchVersion(2)
} else if (Vue.version.startsWith('3.')) {
  switchVersion(3)
} else {
  console.warn(`[vue-demi] Vue version v${Vue.version} is not supported.`)
}

@vue/composition-api 的作用

  • 不是版本判断依据:@vue/composition-api 仅在 <=2.6 场景下作为 polyfill
  • 不会改变版本识别:无法将 isVue3 改为 true
  • 依赖逻辑:只要项目安装的是 Vue 2(含 2.7),无论有没有 @vue/composition-api,vue-demi 暴露的 isVue3 永远是 false

@antv/x6-vue-shape 识别错误问题

问题现象

  1. 错误识别:在 Vue2 项目中,isVue2 返回 falseisVue3 返回 true
  2. 运行时错误:出现 createApp is not a functionObject(...) is not a function 错误
  3. 渲染异常:节点无法正常渲染,连线正常(连线不走 Vue 渲染)

根本原因

  • 双重依赖问题:@antv/x6-vue-shape 自带一份 vue-demi
  • 版本检测混乱:组件内部的 vue-demi 在 postinstall 时可能检测到错误的 Vue3 版本
  • 模块解析优先级:Node 会优先使用组件内部的 vue-demi 副本

常见场景

  1. Monorepo 项目:依赖提升导致版本冲突
  2. Peer 依赖冲突:不同 vue 版本共存
  3. Webpack/Vite alias 劫持:require('vue') 被重定向到 3.x 版本

解决方案

临时解决方案

  1. 删除私有 node_modules
    bash 复制代码
    rm -rf node_modules/@antv/x6-vue-shape/node_modules/vue-demi
  2. 强制使用全局版本
    bash 复制代码
    npm install vue-demi@latest

长期解决方案

1. Webpack alias 配置

javascript 复制代码
resolve.alias.set('vue-demi', path.resolve(__dirname, 'node_modules/vue-demi'))

2. Vite alias 配置

javascript 复制代码
resolve: {
  alias: {
    'vue-demi': 'vue-demi/index.mjs'
  }
}

3. Package.json alias

json 复制代码
"alias": {
  "vue-demi": "./node_modules/vue-demi"
}

4. Postinstall 脚本自动清理

json 复制代码
{
  "scripts": {
    "postinstall": "rm -rf node_modules/@antv/x6-vue-shape/node_modules/vue-demi"
  }
}

5. 改用 peerDependencies

向 @antv/x6-vue-shape 官方提 PR,将 vue-demi 从 dependencies 改为 peerDependencies,由项目侧统一提供版本。

调试建议

当遇到识别错误时,首先确认实际 Vue 版本:

bash 复制代码
node -p "require('vue/package.json').version"

总结

vue-demi 的版本检测机制简单可靠,"识别错误"的根本原因往往是依赖嵌套和版本冲突导致的模块解析问题。通过合理的依赖管理和 alias 配置,可以有效避免这类问题。

相关链接

vue-demi 版本检测机制详解与antv-x6-vue-shape识别错误问题解析 | 博客