Skip to content

Commit

Permalink
fix(hmr): trigger hmr for missing file import errored module after fi…
Browse files Browse the repository at this point in the history
…le creation (#16303)
  • Loading branch information
sapphi-red committed Mar 29, 2024
1 parent dfffea1 commit ffedc06
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/vite/src/node/plugins/importAnalysis.ts
Expand Up @@ -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),
Expand Down
5 changes: 5 additions & 0 deletions packages/vite/src/node/server/hmr.ts
Expand Up @@ -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)
Expand Down
5 changes: 5 additions & 0 deletions packages/vite/src/node/server/moduleGraph.ts
Expand Up @@ -108,6 +108,9 @@ export class ModuleGraph {
Promise<ModuleNode> | ModuleNode
>()

/** @internal */
_hasResolveFailedErrorModules = new Set<ModuleNode>()

constructor(
private resolveId: (
url: string,
Expand Down Expand Up @@ -229,6 +232,8 @@ export class ModuleGraph {
)
}
})

this._hasResolveFailedErrorModules.delete(mod)
}

invalidateAll(): void {
Expand Down
19 changes: 19 additions & 0 deletions playground/hmr/__tests__/hmr.spec.ts
Expand Up @@ -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'])
})
}
2 changes: 2 additions & 0 deletions playground/hmr/missing-file/index.html
@@ -0,0 +1,2 @@
<div>Page</div>
<script type="module" src="main.js"></script>
1 change: 1 addition & 0 deletions playground/hmr/missing-file/main.js
@@ -0,0 +1 @@
import './a.js'

0 comments on commit ffedc06

Please sign in to comment.