Skip to content

Commit ffedc06

Browse files
authored
fix(hmr): trigger hmr for missing file import errored module after file creation (#16303)
1 parent dfffea1 commit ffedc06

File tree

6 files changed

+33
-0
lines changed

6 files changed

+33
-0
lines changed

packages/vite/src/node/plugins/importAnalysis.ts

+1
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
311311
}
312312
// fix#9534, prevent the importerModuleNode being stopped from propagating updates
313313
importerModule.isSelfAccepting = false
314+
moduleGraph._hasResolveFailedErrorModules.add(importerModule)
314315
return this.error(
315316
`Failed to resolve import "${url}" from "${normalizePath(
316317
path.relative(process.cwd(), importerFile),

packages/vite/src/node/server/hmr.ts

+5
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ export async function handleHMRUpdate(
163163
}
164164

165165
const mods = new Set(moduleGraph.getModulesByFile(file))
166+
if (type === 'create') {
167+
for (const mod of moduleGraph._hasResolveFailedErrorModules) {
168+
mods.add(mod)
169+
}
170+
}
166171
if (type === 'create' || type === 'delete') {
167172
for (const mod of getAffectedGlobModules(file, server)) {
168173
mods.add(mod)

packages/vite/src/node/server/moduleGraph.ts

+5
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ export class ModuleGraph {
108108
Promise<ModuleNode> | ModuleNode
109109
>()
110110

111+
/** @internal */
112+
_hasResolveFailedErrorModules = new Set<ModuleNode>()
113+
111114
constructor(
112115
private resolveId: (
113116
url: string,
@@ -229,6 +232,8 @@ export class ModuleGraph {
229232
)
230233
}
231234
})
235+
236+
this._hasResolveFailedErrorModules.delete(mod)
232237
}
233238

234239
invalidateAll(): void {

playground/hmr/__tests__/hmr.spec.ts

+19
Original file line numberDiff line numberDiff line change
@@ -962,4 +962,23 @@ if (!isBuild) {
962962
editFile('css-deps/dep.js', (code) => code.replace(`red`, `green`))
963963
await untilUpdated(() => getColor('.css-deps'), 'green')
964964
})
965+
966+
test('hmr should happen after missing file is created', async () => {
967+
const file = 'missing-file/a.js'
968+
const code = 'console.log("a.js")'
969+
970+
await untilBrowserLogAfter(
971+
() =>
972+
page.goto(viteTestUrl + '/missing-file/index.html', {
973+
waitUntil: 'load',
974+
}),
975+
/connected/, // wait for HMR connection
976+
)
977+
978+
await untilBrowserLogAfter(async () => {
979+
const loadPromise = page.waitForEvent('load')
980+
addFile(file, code)
981+
await loadPromise
982+
}, [/connected/, 'a.js'])
983+
})
965984
}
+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<div>Page</div>
2+
<script type="module" src="main.js"></script>

playground/hmr/missing-file/main.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import './a.js'

0 commit comments

Comments
 (0)