vite-plugin-vue
vite-plugin-vue copied to clipboard
Allow configuring how the hmr Id is generated in @vitejs/plugin-vue
Description
I was trying to import a Vue component from another instance of vite.
The problem lies here: https://github.com/vitejs/vite/blob/c78e4099e502876a2ab23fd8163455d8172ff5b7/packages/plugin-vue/src/utils/descriptorCache.ts#L30 Due to how the id on the descriptor is generated it is impossible to me to change how the css-Scope/__hmrId ... will be generated resulting in a broken hmr runtime and conflicting css.
Using the isProduction flag is not viable because it disables the hmr runtime on vue components.
Suggested solution
Could we introduce another flag or an option to specify how this Id would generate?
There could be an Option that works like isProduction to include the source when creating the id hash
Alternative
No response
Additional context
Repro in StackBlitz: https://stackblitz.com/edit/vitejs-vite-kr3fdz?file=vite-1/index.html
If we then edit the vite-1/src/App.vue the other app gets broken because their internal _hmrId is the same.
Validations
- [X] Follow our Code of Conduct
- [X] Read the Contributing Guidelines.
- [X] Read the docs.
- [X] Check that there isn't already an issue that request the same feature to avoid creating a duplicate.
This feels like a very niche usecase which many plugins won't support, so it's not only a problem with plugin-vue. What is your usecase needing to accessing Vue components from a different server?
I am trying to create some kind of micro-frontend where I am importing other Vue apps from different packages within a workspace. I would like to have multiple vite instances serving the different projects so that the main application can dynamically import these and still utilize the hot reload functionality. Because how the projects are structured, the logic determining how the _hmrId is generated, results in the same id for every component that have the same root-relative path (ex. src/App.vue => "7a7a37b1").
I have written one workaround that tries to rewrite the generated id after the plugin transformed the SFC, but was unable to catch every place where the generated id is used.
@PPetau could you share your workaround? I have a similar usecase: I have a production app that is extendable with plugins. While the user develops a new plugin I want HMR. I can consume the plugin component in my app directly from the plugin's vite dev server, but the ids won't match so only global styles and scripts are working right now.
Hi @arnoson, this is the snipped that runs in the transform hook and replaces the generated hmrIds (only of the .vue files).
const hmrUniqueIdentifier = "your_custom_id_namespace";
if (/\.vue/.test(id)) {
if (code.includes("_sfc_main.__hmrId")) {
const magicString = new MagicString(code);
const hmrId = code.match(
/_sfc_main\.__hmrId\s*\=\s*["'](.+)["']/m
)?.[1];
if (hmrId) {
magicString.replace(
new RegExp(hmrId, "g"),
hmrId + hmrUniqueIdentifier
);
return {
code: magicString.toString(),
map: magicString.generateMap()
};
}
}