Skip to content

Commit

Permalink
fix(hmr): trigger page reload when calling invalidate on root module (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
ArnaudBarre committed May 14, 2024
1 parent 65eb48f commit 2b61cc3
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 6 deletions.
3 changes: 2 additions & 1 deletion packages/vite/src/node/server/hmr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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[] = []
Expand Down
13 changes: 11 additions & 2 deletions playground/hmr/__tests__/hmr.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) =>
Expand Down Expand Up @@ -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) =>
Expand All @@ -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(
Expand Down
1 change: 0 additions & 1 deletion playground/hmr/hmr.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand Down
4 changes: 3 additions & 1 deletion playground/hmr/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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>
Expand Down
2 changes: 1 addition & 1 deletion playground/hmr/invalidation/parent.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
16 changes: 16 additions & 0 deletions playground/hmr/invalidation/root.js
Original file line number Diff line number Diff line change
@@ -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'
}

0 comments on commit 2b61cc3

Please sign in to comment.