fix(hmr): trigger page reload when calling invalidate on root module (#16636)

This commit is contained in:
Arnaud Barré 2024-05-14 16:01:36 +02:00 committed by GitHub
parent 65eb48f1c6
commit 2b61cc39a9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 33 additions and 6 deletions

View File

@ -228,7 +228,8 @@ export function updateModules(
const updates: Update[] = []
const invalidatedModules = new Set<ModuleNode>()
const traversedModules = new Set<ModuleNode>()
let needFullReload: HasDeadEnd = false
// Modules could be empty if a root module is invalidated via import.meta.hot.invalidate()
let needFullReload: HasDeadEnd = modules.length === 0
for (const mod of modules) {
const boundaries: PropagationBoundary[] = []

View File

@ -154,7 +154,7 @@ if (!isBuild) {
})
test('invalidate', async () => {
const el = await page.$('.invalidation')
const el = await page.$('.invalidation-parent')
await untilBrowserLogAfter(
() =>
editFile('invalidation/child.js', (code) =>
@ -182,7 +182,7 @@ if (!isBuild) {
page2 = await browser.newPage()
await page2.goto(viteTestUrl)
const el = await page.$('.invalidation')
const el = await page.$('.invalidation-parent')
await untilBrowserLogAfter(
() =>
editFile('invalidation/child.js', (code) =>
@ -208,6 +208,15 @@ if (!isBuild) {
}
})
test('invalidate on root triggers page reload', async () => {
editFile('invalidation/root.js', (code) => code.replace('Init', 'Updated'))
await page.waitForEvent('load')
await untilUpdated(
async () => (await page.$('.invalidation-root')).textContent(),
'Updated',
)
})
test('soft invalidate', async () => {
const el = await page.$('.soft-invalidation')
expect(await el.textContent()).toBe(

View File

@ -1,7 +1,6 @@
import { virtual } from 'virtual:file'
import { foo as depFoo, nestedFoo } from './hmrDep'
import './importing-updated'
import './invalidation/parent'
import './file-delete-restore'
import './optional-chaining/parent'
import './intermediate-file-delete'

View File

@ -7,6 +7,7 @@
</div>
<button class="virtual-update">update virtual module</button>
<script type="module" src="./invalidation/root.js"></script>
<script type="module" src="./hmr.ts"></script>
<style>
.import-image {
@ -24,7 +25,8 @@
<div class="toRemove"></div>
<div class="virtual"></div>
<div class="soft-invalidation"></div>
<div class="invalidation"></div>
<div class="invalidation-parent"></div>
<div class="invalidation-root"></div>
<div class="custom-communication"></div>
<div class="css-prev"></div>
<div class="css-post"></div>

View File

@ -6,4 +6,4 @@ if (import.meta.hot) {
console.log('(invalidation) parent is executing')
document.querySelector('.invalidation').innerHTML = value
document.querySelector('.invalidation-parent').innerHTML = value

View File

@ -0,0 +1,16 @@
import './parent.js'
if (import.meta.hot) {
// Need to accept, to register a callback for HMR
import.meta.hot.accept(() => {
// Triggers full page reload because no importers
import.meta.hot.invalidate()
})
}
const root = document.querySelector('.invalidation-root')
// Non HMR-able behaviour
if (!root.innerHTML) {
root.innerHTML = 'Init'
}