Description
As a developer migrating to Vite I want HMR to work with circular imports.
HMR currently fallbacks to full-reload when an exception is thrown during import:
|
if (isWithinCircularImport) { |
|
importPromise.catch(() => { |
|
console.info( |
|
`[hmr] ${acceptedPath} failed to apply HMR as it's within a circular import. Reloading page to reset the execution order. ` + |
|
`To debug and break the circular import, you can run \`vite --debug hmr\` to log the circular dependency path if a file change triggered it.`, |
|
) |
|
pageReload() |
|
}) |
|
} |
This happens when modules with the isWithinCircularImport flag are imported in a different than the original order.
Example:
Main imports Links
Links imports PageA, PageB, ...
PageA imports Links
PageB imports Links
- ...
Simplified content of the Links module:
import PageA from "./PageA";
import PageB from "./PageB";
export const pageA = defineLink(PageA);
export const pageB = defineLink(PageB);
...
Modules PageA, PageB, ... define pages with their parameters and render links to other pages.
When Links is changed, HMR posts js-update with Links, which is fine.
However, when PageA is changed, HMR posts js-update with PageA, which fails with ReferenceError: Cannot access 'UsersPage' before initialization. (The exception is thrown because PageA imports the invalidated module Links, which references to PageA that has not yet been initialized.)
Suggested solution
The solution is to change HMR so that it imports modules in the same order as they were initially imported.
For the example above:
When PageA is changed, send js-update with Links instead of PageA.
Alternative
No response
Additional context
I found the following PRs that attempts to address HMR issues with circular imports:
And the following issues:
Validations
Description
As a developer migrating to Vite I want HMR to work with circular imports.
HMR currently fallbacks to full-reload when an exception is thrown during import:
vite/packages/vite/src/client/client.ts
Lines 159 to 167 in 2bc5d3d
This happens when modules with the
isWithinCircularImportflag are imported in a different than the original order.Example:
MainimportsLinksLinksimportsPageA,PageB, ...PageAimportsLinksPageBimportsLinksSimplified content of the
Linksmodule:Modules
PageA,PageB, ... define pages with their parameters and render links to other pages.When
Linksis changed, HMR postsjs-updatewithLinks, which is fine.However, when
PageAis changed, HMR postsjs-updatewithPageA, which fails withReferenceError: Cannot access 'UsersPage' before initialization. (The exception is thrown becausePageAimports the invalidated moduleLinks, which references toPageAthat has not yet been initialized.)Suggested solution
The solution is to change HMR so that it imports modules in the same order as they were initially imported.
For the example above:
When
PageAis changed, sendjs-updatewithLinksinstead ofPageA.Alternative
No response
Additional context
I found the following PRs that attempts to address HMR issues with circular imports:
And the following issues:
Validations