Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 37 additions & 5 deletions playground/hmr/__tests__/hmr.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
editFile,
getBg,
getColor,
gotoLatestBuild,
hotUpdatedLog,
isBuild,
isBundledDev,
Expand Down Expand Up @@ -524,8 +523,10 @@ if (!isBuild) {
const CONNECTED = /connected/

const baseDir = 'accept-exports'
const openPage = (testDir: string) =>
gotoLatestBuild(`${viteTestUrl}/${testDir}/`)
const openPage = async (testDir: string) => {
await page.goto(`${viteTestUrl}/${testDir}/`, { waitUntil: 'commit' })
await page.waitForSelector('html[data-hmr-ready="true"]')
}

describe('when all used exports are accepted', () => {
const testDir = baseDir + '/main-accepted'
Expand Down Expand Up @@ -1144,7 +1145,10 @@ if (!isBuild) {
"export { value as childValue } from './child'",
),
)
}, 'file-delete-restore/child.js hot data after prune: undefined')
}, [
'file-delete-restore/child.js hot data after prune: undefined',
hotUpdatedLog(parentFile),
])
await expect
.poll(() => page.textContent('.file-delete-restore'))
.toMatch('parent:child')
Expand Down Expand Up @@ -1352,7 +1356,35 @@ if (!isBuild) {
)

test('import.meta.hot?.accept', async () => {
await gotoLatestBuild(viteTestUrl)
if (isBundledDev) {
// Navigation can finish before the new HMR client registers.
let delayRegistration = true
await page.routeWebSocket('**', (socket) => {
const server = socket.connectToServer()
const queuedMessages: (string | Buffer)[] = []
let queueMessages = false
socket.onMessage((message) => {
if (
delayRegistration &&
String(message).includes('vite:client-connected')
) {
delayRegistration = false
queueMessages = true
setTimeout(() => {
for (const queued of queuedMessages) server.send(queued)
queueMessages = false
}, 500)
}
if (queueMessages) {
queuedMessages.push(message)
} else {
server.send(message)
}
})
})
}
await page.goto(viteTestUrl)
await page.waitForSelector('html[data-hmr-ready="true"]')

const el = page.locator('.optional-chaining')
await untilBrowserLogAfter(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { beforeAll, describe, expect, it } from 'vitest'
import {
editFile,
gotoLatestBuild,
hotUpdatedLog,
isBuild,
page,
Expand All @@ -11,8 +10,10 @@ import {

describe.runIf(!isBuild)('acceptExports with hmrPartialAccept off', () => {
const CONNECTED = /connected/
const openPage = (testDir: string) =>
gotoLatestBuild(`${viteTestUrl}/${testDir}/`)
const openPage = async (testDir: string) => {
await page.goto(`${viteTestUrl}/${testDir}/`, { waitUntil: 'commit' })
await page.waitForSelector('html[data-hmr-ready="true"]')
}

describe('importer that uses only accepted exports', () => {
const testDir = 'accept-exports/main-accepted'
Expand Down
27 changes: 27 additions & 0 deletions playground/hmr/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,33 @@ export default defineConfig(({ command }) => ({
},
},
plugins: [
// A round trip settles fallback reloads and client registration before edits.
{
name: 'test-hmr-ready',
apply: 'serve',
configureServer(server) {
server.environments.client.hot.on('test:ready', (_data, client) => {
client.send('test:ready')
})
},
transformIndexHtml: {
order: 'pre',
handler() {
return [
{
tag: 'script',
attrs: { type: 'module' },
children: `
import.meta.hot.on('test:ready', () => {
document.documentElement.dataset.hmrReady = 'true'
})
import.meta.hot.send('test:ready')
`,
},
]
},
},
},
{
name: 'mock-custom',
async hotUpdate({ file, read }) {
Expand Down
11 changes: 0 additions & 11 deletions playground/test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import {
page,
sourcemapSnapshot,
testDir,
viteServer,
watchBuilds,
} from './vitestSetupUtils'

Expand Down Expand Up @@ -282,16 +281,6 @@ export function readDepOptimizationMetadata(
)
}

export async function gotoLatestBuild(url: string): Promise<void> {
if (isBundledDev) {
// Earlier HMR edits leave the bundled-dev output stale. Opening a page then
// serves the fallback page first, which reloads into the real page later.
const bundledDev = viteServer.environments.client.bundledDev as any
await bundledDev.devEngine.ensureLatestBuildOutput()
}
await page.goto(url)
}

/**
* Wait for every output containing the edited module to finish rebuilding.
* Workaround for Rolldown emitting END per output before all outputs finish:
Expand Down
Loading