-
-
Notifications
You must be signed in to change notification settings - Fork 7.3k
Description
Clear and concise description of the problem
When developing a library with HMR support, I want to be able to support HMR with the least code from the end user
Suggested solution
When working with a library that is meant to be used in many files like Pinia for Vue, each HMR code needs to be placed inside of the store file to be able to handle the HMR. If placed outside, let's say in the main.ts
entry point, you need to manually import all of the stores (using a glob doesn't seem to work):
import { acceptHMRUpdate, defineStore } from 'pinia'
export const useCounter = defineStore({
// optios
})
if (import.meta.hot) {
// acceptHMRUpdate creates a function that handles the update of the store in place
import.meta.hot.accept(acceptHMRUpdate(useCounter, import.meta.hot))
}
That useCounter
is imported in Vue component or JS files all across the app.
When reading the docs, I feel like this limitation is intended but it makes it quite cumbersome to add HMR support for stores. It would be nice if we could do something like this in the entry point or one single file of the app:
import.meta.hot!.accept(import.meta.glob('./stores/*.ts',
(newModule) => {
// handle the update
})
Alternative
I tried importing all of the modules with a glob in the entrypoint (main.ts) but that doesn't work:
// src/main.ts
import { acceptHMRUpdate, createPinia, isUseStore } from 'pinia'
// rest of the code
if (import.meta.hot) {
const stores = import.meta.glob('./stores/*.ts')
for (const filePath in stores) {
console.log('configuring HMR for', filePath)
stores[filePath]().then((mod) => {
for (const exportName in mod) {
const storeDef = mod[exportName]
if (isUseStore(storeDef)) {
console.log(`Detected store "${storeDef.$id}"`)
import.meta.hot!.accept(
filePath,
acceptHMRUpdate(storeDef, import.meta.hot)
)
}
}
})
}
It doesn't even enter the function returned by acceptHMRUpdate()
.
I imagine that creating a vite plugin to rewrite all of the files in a specific folder to add support for HMR is possible but it means users need to add a vite plugin when installing the lib and differently from .vue
files, stores have js
or ts
extensions, so they need to be filtered based on their content.
Additional context
The code from above is testable at https://github.com/posva/pinia/tree/test/globalhmr with yarn play
. The source code is located at playground/src
and src/hmr.ts
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn't already an issue that request the same feature to avoid creating a duplicate.