Subscribe on changes!

Reactive issue in composition API when compiling as library

avatar
Aug 12th 2022

Vue version

3.2.36

Link to minimal reproduction

https://github.com/jsbr/vue-issue-reactive-composite-api

Steps to reproduce

Try the minimal reproduction project (check the readme)

or:

  1. Create a simple project with a basic composite api component:
<script setup lang="ts">
import { reactive } from 'vue';
const data = reactive({
    count: 0
})

setInterval(()=>data.count++,1000);
</script>
<template>
    <h3>Vite Composite Api: {{data.count}}</h3>
</template>
  1. build it, configure the package.json
  2. create a second project
  3. install the previous project into the new one.
  4. Use the component previously create in the new project:
<script setup lang="ts">
import {CompApiTestVite} from 'test-lib-vite';
</script>
<template>
  <CompApiTestVite></CompApiTestVite>
</template>
  1. npm run serve (for vue-cli) or vite build (for vite.js)

What is expected?

Component should be reactive and increment the counter (in the exemple)

What is actually happening?

Counter don't increment when:

  • Component is used in other project in dev and prod for vue-cli
  • Component is used in other project and build in prod with vite.js

Counter increment when:

  • Executed in the library project
  • Executed in dev with vite.js

System Info

System:
    OS: Linux 5.10 Debian GNU/Linux 11 (bullseye) 11 (bullseye)
    CPU: (12) x64 Intel(R) Core(TM) i7-10850H CPU @ 2.70GHz
  Binaries:
    Node: 16.15.1 - ~/.nvm/versions/node/v16.15.1/bin/node
    Yarn: Not Found
    npm: 8.11.0 - ~/.nvm/versions/node/v16.15.1/bin/npm
  Browsers:
    Vivaldi
    Chrome: Not Found
    Firefox: 101.0.1
  npmGlobalPackages:
    @vue/cli: Not Found

Any additional comments?

Previously thinking is was a vuecli (see: https://github.com/vuejs/vue-cli/issues/7196) Now found it also happens on vite.js when build in production (vitest build)

When we use Composition Api for a component library and use it in another vue project, the components are no longer reactive.

avatar
Aug 13th 2022

Event though you externalize vue in the lib folders, it's still existing in those folders' node_modules.

When you include these projects into the apps via file://..., the 'vue' imports in your lib files will import vue from their node_modules folder, while your app's code will import vue from their node_modules folder.

So you end up with Vue being included in the app two times, which breaks Vue's singletons used for tracking the currently active component scope etc. This is a local problem, it would not occur if you published your libs to npm and properly installed from the there as real packages.

For vite, the solution would be to use resolve.dedupe: ['vue'], for webpack/Vue CLI, you would have to create an alias for 'vue$' resolving to an absolute path.