Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: correctly resolve hmr dep ids and fallback to url #18840

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 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
14 changes: 12 additions & 2 deletions packages/vite/src/node/plugins/importAnalysis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -753,9 +753,19 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
// normalize and rewrite accepted urls
const normalizedAcceptedUrls = new Set<string>()
patricklx marked this conversation as resolved.
Show resolved Hide resolved
for (const { url, start, end } of acceptedUrls) {
const [normalized] = await moduleGraph.resolveUrl(toAbsoluteUrl(url))
let normalized
const resolved = await this.resolve(url, importerModule.id || undefined)
patricklx marked this conversation as resolved.
Show resolved Hide resolved
if (resolved?.id) {
const mod = moduleGraph.getModuleById(resolved.id)
normalized = mod?.url
}
if (!normalized) {
const [resolved] = await moduleGraph.resolveUrl(toAbsoluteUrl(url))
normalized = resolved
}
patricklx marked this conversation as resolved.
Show resolved Hide resolved
normalizedAcceptedUrls.add(normalized)
str().overwrite(start, end, JSON.stringify(normalized), {
const hmrAccept = normalizeHmrUrl(normalized)
str().overwrite(start, end, JSON.stringify(hmrAccept), {
contentOnly: true,
})
}
sapphi-red marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
23 changes: 23 additions & 0 deletions playground/hmr/__tests__/hmr.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,29 @@ if (!isBuild) {
}, '[wow]1')
})

test('handle virtual module accept updates', async () => {
await page.goto(viteTestUrl)
const el = await page.$('.virtual-dep')
expect(await el.textContent()).toBe('0')
editFile('importedVirtual.js', (code) => code.replace('[success]', '[wow]'))
await untilUpdated(async () => {
const el = await page.$('.virtual-dep')
return await el.textContent()
}, '[wow]')
})

test('invalidate virtual module and accept', async () => {
await page.goto(viteTestUrl)
const el = await page.$('.virtual-dep')
expect(await el.textContent()).toBe('0')
const btn = await page.$('.virtual-update-dep')
btn.click()
await untilUpdated(async () => {
const el = await page.$('.virtual-dep')
return await el.textContent()
}, '[wow]2')
})

test('keep hmr reload after missing import on server startup', async () => {
const file = 'missing-import/a.js'
const importCode = "import 'missing-modules'"
Expand Down
17 changes: 17 additions & 0 deletions playground/hmr/hmr.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { virtual } from 'virtual:file'
import { virtual as virtualDep } from 'virtual:file-dep'
import { foo as depFoo, nestedFoo } from './hmrDep'
import './importing-updated'
import './file-delete-restore'
Expand All @@ -14,17 +15,29 @@ text('.app', foo)
text('.dep', depFoo)
text('.nested', nestedFoo)
text('.virtual', virtual)
text('.virtual-dep', virtualDep)
text('.soft-invalidation', softInvalidationMsg)
setImgSrc('#logo', logo)
setImgSrc('#logo-no-inline', logoNoInline)

text('.virtual-dep', 0)

const btn = document.querySelector('.virtual-update') as HTMLButtonElement
btn.onclick = () => {
if (import.meta.hot) {
import.meta.hot.send('virtual:increment')
}
}

const btnDep = document.querySelector(
'.virtual-update-dep',
) as HTMLButtonElement
btnDep.onclick = () => {
if (import.meta.hot) {
import.meta.hot.send('virtual:increment', '-dep')
}
}

if (import.meta.hot) {
import.meta.hot.accept(({ foo }) => {
console.log('(self-accepting 1) foo is now:', foo)
Expand Down Expand Up @@ -55,6 +68,10 @@ if (import.meta.hot) {
handleDep('single dep', foo, nestedFoo)
})

import.meta.hot.accept('virtual:file-dep', ({ virtual }) => {
text('.virtual-dep', virtual)
})

import.meta.hot.accept(['./hmrDep'], ([{ foo, nestedFoo }]) => {
handleDep('multi deps', foo, nestedFoo)
})
Expand Down
2 changes: 2 additions & 0 deletions playground/hmr/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
/>
</div>
<button class="virtual-update">update virtual module</button>
<button class="virtual-update-dep">update virtual module via accept</button>

<script type="module" src="./invalidation/root.js"></script>
<script type="module" src="./hmr.ts"></script>
Expand All @@ -24,6 +25,7 @@
<div class="custom"></div>
<div class="toRemove"></div>
<div class="virtual"></div>
<div class="virtual-dep"></div>
<div class="soft-invalidation"></div>
<div class="invalidation-parent"></div>
<div class="invalidation-root"></div>
Expand Down
4 changes: 4 additions & 0 deletions playground/hmr/modules.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
declare module 'virtual:file' {
export const virtual: string
}

declare module 'virtual:file-dep' {
export const virtual: string
}
15 changes: 7 additions & 8 deletions playground/hmr/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,23 +45,22 @@ function virtualPlugin(): Plugin {
return {
name: 'virtual-file',
resolveId(id) {
if (id === 'virtual:file') {
return '\0virtual:file'
if (id.startsWith('virtual:file')) {
return '\0' + id
}
},
load(id) {
if (id === '\0virtual:file') {
if (id.startsWith('\0virtual:file')) {
return `\
import { virtual as _virtual } from "/importedVirtual.js";
export const virtual = _virtual + '${num}';`
}
},
configureServer(server) {
server.environments.client.hot.on('virtual:increment', async () => {
const mod =
await server.environments.client.moduleGraph.getModuleByUrl(
'\0virtual:file',
)
server.environments.client.hot.on('virtual:increment', async (suffix) => {
const mod = await server.environments.client.moduleGraph.getModuleById(
'\0virtual:file' + (suffix || ''),
)
if (mod) {
num++
server.environments.client.reloadModule(mod)
Expand Down
Loading