Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

微前端架构下,子应用重复注册 composition-api 插件失败,导致插件提供的响应式 API 不可用 #876

Closed
liyongning opened this issue Dec 23, 2021 · 0 comments

Comments

@liyongning
Copy link
Contributor

  • 微前端架构(主应用 A、子应用 B、子应用 C)
  • 主应用通过 CDN 引入 vuejs 库
  • 子应用设置 externals vue,此时这套架构下的应用会共用全局对象(window)上的 Vue。

    注意这里不考虑子应用重命名 Vue 的操作,因为不是一个普适的方法,假如我有 100 个子应用,这个操作就很恐怖了

  • 这时,在浏览器打开子应用 B 中的某个页面,这时一切正常,不会有问题
  • 接下来从子应用 B 进入子应用 C,就会出问题了,提示插件已经被注册过了,且子应用 C 中的响应式 API (比如 reactive)调用也会报错,理由如下:
    • 从第一个子应用进入第二个子应用(从 B 进入 C),当在子应用中引用 composition-api 时(import CompositionAPI from '@vue/composition-api),会触发插件中的如下代码:
    if (typeof window !== 'undefined' && window.Vue) {
      window.Vue.use(Plugin)
    }
    • 进而会注册插件,执行插件的 install 方法,从而触发 install 中的检测方法 isVueRegistered,代码如下:
      export function install(Vue: VueConstructor) {
        if (isVueRegistered(Vue)) {
          if (__DEV__) {
            warn(
              '[vue-composition-api] already installed. Vue.use(VueCompositionAPI) should be called only once.'
            )
          }
          return
        }
        // ....
      }
    • 接下来触发 isVueRegistered 方法
      export function isVueRegistered(Vue: VueConstructor) {
        return hasOwn(Vue, PluginInstalledFlag)
      }
    • 因为子应用共用全局对象上的 Vue,所以 isVueRegistered 方法会返回 true
    • 导致 install 方法无法继续往下执行,也就是说子应用 C 中的 vueConstructor 变量是 null
    • image
    • 这时插件虽然在路由进入子应用 B 时已经在 Vue 上注册了,但是当切换到子应用 C 时由于 install 被提前终止,导致下面的 setVueConstructor 没有执行,所以 vueConstructor 变量是 null,代码如下:
      • image
      • image
    • 这时子应用执行响应式 API 时,比如 reactive,执行过程如下:
      • image
      • image
      • image
    • 所以这时候控制台就报错,找不到 Vue

=============================================================================================

针对以上问题,有如下解决办法,可以增强 isVueRegistered 方法的判断能力,比如:
image
目前通过给插件 打补丁 的方式在业务中运行该方案,经验证是可行的,也没发现什么副作用,composition-api 的单元测试也能正常跑过

liyongning added a commit to liyongning/composition-api that referenced this issue Dec 24, 2021
@antfu antfu closed this as completed in 3c2ad93 Dec 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant