From 4ed9c62fe1d442088d601bfd83c971f2ec9ce9f1 Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Fri, 29 Mar 2024 13:12:04 +0900 Subject: [PATCH 1/3] fix(hmr): don't mutate module graph when collecting modules --- packages/vite/src/node/server/hmr.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vite/src/node/server/hmr.ts b/packages/vite/src/node/server/hmr.ts index cf28591db056de..c5f5f8254941f5 100644 --- a/packages/vite/src/node/server/hmr.ts +++ b/packages/vite/src/node/server/hmr.ts @@ -162,7 +162,7 @@ export async function handleHMRUpdate( return } - const mods = moduleGraph.getModulesByFile(file) || new Set() + const mods = new Set(moduleGraph.getModulesByFile(file)) if (type === 'create' || type === 'delete') { for (const mod of getAffectedGlobModules(file, server)) { mods.add(mod) From cf26378baa3244468eb756e89f61610c1ccc372e Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Fri, 29 Mar 2024 12:18:36 +0900 Subject: [PATCH 2/3] test(hmr): trigger hmr for missing file import errored module after file creation --- playground/hmr/__tests__/hmr.spec.ts | 19 +++++++++++++++++++ playground/hmr/missing-file/index.html | 2 ++ playground/hmr/missing-file/main.js | 1 + 3 files changed, 22 insertions(+) create mode 100644 playground/hmr/missing-file/index.html create mode 100644 playground/hmr/missing-file/main.js diff --git a/playground/hmr/__tests__/hmr.spec.ts b/playground/hmr/__tests__/hmr.spec.ts index 5f82716df9203d..138cff2cb56b40 100644 --- a/playground/hmr/__tests__/hmr.spec.ts +++ b/playground/hmr/__tests__/hmr.spec.ts @@ -962,4 +962,23 @@ if (!isBuild) { editFile('css-deps/dep.js', (code) => code.replace(`red`, `green`)) await untilUpdated(() => getColor('.css-deps'), 'green') }) + + test('hmr should happen after missing file is created', async () => { + const file = 'missing-file/a.js' + const code = 'console.log("a.js")' + + await untilBrowserLogAfter( + () => + page.goto(viteTestUrl + '/missing-file/index.html', { + waitUntil: 'load', + }), + /connected/, // wait for HMR connection + ) + + await untilBrowserLogAfter(async () => { + const loadPromise = page.waitForEvent('load') + addFile(file, code) + await loadPromise + }, [/connected/, 'a.js']) + }) } diff --git a/playground/hmr/missing-file/index.html b/playground/hmr/missing-file/index.html new file mode 100644 index 00000000000000..cfbd07a1e44286 --- /dev/null +++ b/playground/hmr/missing-file/index.html @@ -0,0 +1,2 @@ +
Page
+ diff --git a/playground/hmr/missing-file/main.js b/playground/hmr/missing-file/main.js new file mode 100644 index 00000000000000..999801e4dd1061 --- /dev/null +++ b/playground/hmr/missing-file/main.js @@ -0,0 +1 @@ +import './a.js' From 9aaaaa06fdc9171868df77d900af2e24d43cb6b3 Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Fri, 29 Mar 2024 12:19:09 +0900 Subject: [PATCH 3/3] fix(hmr): trigger hmr for missing file import errored module after file creation --- packages/vite/src/node/plugins/importAnalysis.ts | 1 + packages/vite/src/node/server/hmr.ts | 5 +++++ packages/vite/src/node/server/moduleGraph.ts | 5 +++++ 3 files changed, 11 insertions(+) diff --git a/packages/vite/src/node/plugins/importAnalysis.ts b/packages/vite/src/node/plugins/importAnalysis.ts index 6d758e04cd807c..a4c1b9fd38a033 100644 --- a/packages/vite/src/node/plugins/importAnalysis.ts +++ b/packages/vite/src/node/plugins/importAnalysis.ts @@ -311,6 +311,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { } // fix#9534, prevent the importerModuleNode being stopped from propagating updates importerModule.isSelfAccepting = false + moduleGraph._hasResolveFailedErrorModules.add(importerModule) return this.error( `Failed to resolve import "${url}" from "${normalizePath( path.relative(process.cwd(), importerFile), diff --git a/packages/vite/src/node/server/hmr.ts b/packages/vite/src/node/server/hmr.ts index c5f5f8254941f5..3d5aedb2378836 100644 --- a/packages/vite/src/node/server/hmr.ts +++ b/packages/vite/src/node/server/hmr.ts @@ -163,6 +163,11 @@ export async function handleHMRUpdate( } const mods = new Set(moduleGraph.getModulesByFile(file)) + if (type === 'create') { + for (const mod of moduleGraph._hasResolveFailedErrorModules) { + mods.add(mod) + } + } if (type === 'create' || type === 'delete') { for (const mod of getAffectedGlobModules(file, server)) { mods.add(mod) diff --git a/packages/vite/src/node/server/moduleGraph.ts b/packages/vite/src/node/server/moduleGraph.ts index 02a30fb7af315a..c0554dd156481a 100644 --- a/packages/vite/src/node/server/moduleGraph.ts +++ b/packages/vite/src/node/server/moduleGraph.ts @@ -108,6 +108,9 @@ export class ModuleGraph { Promise | ModuleNode >() + /** @internal */ + _hasResolveFailedErrorModules = new Set() + constructor( private resolveId: ( url: string, @@ -229,6 +232,8 @@ export class ModuleGraph { ) } }) + + this._hasResolveFailedErrorModules.delete(mod) } invalidateAll(): void {