-
-
Notifications
You must be signed in to change notification settings - Fork 8k
Support resolve import.meta.hot.accept dep #16375
Description
Description
Vite is a great project, and it does an excellent job with code hot reloading. However, I feel that it could be more friendly towards monorepos. When I tried to depend on other packages within a monorepo, I encountered some issues. The 'accept' feature tracks dependencies based on file paths, but when my module is an external module (relative to the current module within the workspace), I found it inconvenient to register the paths. I believe this project could potentially provide some useful APIs to address such needs.
import.meta.hot.accept('@foo/bar', newModule => {
// never trigger
})
import.meta.hot.accept('@foo/bar/a', newModule => {
// never trigger
})
import.meta.hot.accept('foo', newModule => {
// never trigger
})
// I have to write it this way, but it lacks any scalability.
import.meta.hot.accept('/@fs/Users/username/to-the-project/packages/core/src/index.ts', ()=> { ... })Alternatively, I could redefine a file and then reexport the module.
// src/reexport.core.ts
export * from '@foo/core'
// src/index.ts
import.meta.hot.accept('./reexport.core.ts', async newModule => { ... })This method is incredibly inconvenient and becomes a pure burden when it comes to writing code.
Suggested solution
- import string deifne
// vite.config.ts
export default {
importDefine: { workspace: getWorkspace() }
}
// src/index.ts
import.meta.hot.accept('<workspace>/packages/core', () => { ... })
// or
import.meta.hot.accept('workspace:/packages/core', () => { ... })
// or
import.meta.hot.accept('/@workspace/packages/core', () => { ... })- auto detect string path
// external pacakge
import.meta.hot.accept('xx', () => { ... })
import.meta.hot.accept('xx/yy', () => { ... })
import.meta.hot.accept('@xx/yy', () => { ... })
import.meta.hot.accept('@xx/yy/zz', () => { ... })
// relative path
import.meta.hot.accept('./a', () => { ... })
import.meta.hot.accept('../a', () => { ... })
// absolute path
import.meta.hot.accept('/@fs/a', () => { ... })vite/packages/vite/src/shared/hmr.ts
Lines 74 to 86 in b05c405
| accept(deps?: any, callback?: any): void { | |
| if (typeof deps === 'function' || !deps) { | |
| // self-accept: hot.accept(() => {}) | |
| this.acceptDeps([this.ownerPath], ([mod]) => deps?.(mod)) | |
| } else if (typeof deps === 'string') { | |
| // explicit deps | |
| this.acceptDeps([deps], ([mod]) => callback?.(mod)) | |
| } else if (Array.isArray(deps)) { | |
| this.acceptDeps(deps, callback) | |
| } else { | |
| throw new Error(`invalid hot.accept() usage.`) | |
| } | |
| } |
With this approach, it seems that I only need to check and resolve the 'deps' parameter at this point. I have tried it, but I'm not sure why there is a '/src' added before the relative path. I couldn't figure out when it was added, so I paused the experimental changes using this method.
Alternative
No response
Additional context
No response
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.