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

Vite dependency pre-bundling breaks Vue Plugin functions on development #8158

Closed
7 tasks done
duannx opened this issue May 13, 2022 · 1 comment
Closed
7 tasks done

Comments

@duannx
Copy link

duannx commented May 13, 2022

Describe the bug

Problem

Vite does pre-bundling for dependency but it just caches JS file and leaves the .vue file to the original file at node_modules/the-plugin-package-name. It will lead to bugs when the plugin uses the Singleton pattern to manage states.

Because the Singleton file might be cached on the node_modules/.vite/deps file, but when the .vue file imports it, the .vue file would use the instance from node_module/the-plugin-package-name. And two instances of the Singleton will be created. One lives in node_modules/.vite/deps and the others lives in node_modules/the-plugin-package-name.

Let's consider this example. I use @meforma/vue-toaster plugin. The plugin have a Toaster.vue file and a Singleton event-bus.js to manage show/hide state of the toast. Vite cache event bus on node_modules/.vite/deps but leave the Toaster.vue to the original file

// The .vue file is point to original file
// node_modules/@meforma/vue-toaster/src/index.js
import Toaster2 from "/Users/admin/Work/test-projects/vite-demo-vue-plugin/node_modules/@meforma/vue-toaster/src/Toaster.vue";

// node_modules/@meforma/vue-toaster/src/api.js
import Toaster from "/Users/admin/Work/test-projects/vite-demo-vue-plugin/node_modules/@meforma/vue-toaster/src/Toaster.vue";

// The js file is cached here so Singleton pattern will breaks
// node_modules/@meforma/vue-toaster/src/helpers/event-bus.js
var Event = class {
  constructor() {
    this.queue = {};
  }
...
}

When the Toaster.vue uses the eventBus, it will use the instance in node_modules/@meforma/vue-toaster/. But when we call toast.clear() from our Vue app the clear method will use the eventBus instance in node_modules/.vite/deps. They are two different instances so the clear method will not work

Workaround

The problem will be solved by excluding the package from pre-bundling by optimizeDeps.entries

export default defineConfig({
  optimizeDeps: {
    exclude: ['@meforma/vue-toaster']
  }
})

However, it's a not long-term fix and the bug will consume hours of debugging before leading to this solution. This can happen to any Vue/React plugin where there some files can't be cached by Vite.

I think Vite should explicitly document this to reduce the effort of developers when facing this issue. Or Vite should automatically ignore from pre-bundling these packages that has some files that can't be cached

Reproduction

https://github.com/duannx/vite-demo-vue-plugin

System Info

System:
    OS: macOS 12.3.1
    CPU: (8) x64 Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz
    Memory: 811.86 MB / 16.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 16.14.2 - ~/.nvm/versions/node/v16.14.2/bin/node
    Yarn: 1.22.18 - ~/.yarn/bin/yarn
    npm: 8.5.0 - ~/.nvm/versions/node/v16.14.2/bin/npm
  Browsers:
    Chrome: 101.0.4951.64
    Firefox: 98.0.2
    Safari: 15.4
  npmPackages:
    @vitejs/plugin-vue: ^2.3.3 => 2.3.3 
    vite: ^2.9.9 => 2.9.9

Used Package Manager

yarn

Logs

No response

Validations

@bluwy
Copy link
Member

bluwy commented May 13, 2022

Duplicate of #3910. There hasn't been a lot of movement regarding it, but you can take a look at

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants