From 40ee2457a7be80001e3d88ad9394c0591f620dd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Barr=C3=A9?= Date: Tue, 17 Oct 2023 18:39:08 +0200 Subject: [PATCH] fix(hmr): add timestamp for assets in dev (#13371) --- packages/vite/src/node/plugins/asset.ts | 4 +++- playground/assets/__tests__/assets.spec.ts | 14 ++++++++------ .../relative-base/relative-base-assets.spec.ts | 4 +++- .../runtime-base/runtime-base-assets.spec.ts | 4 +++- .../__tests__/url-base/url-base-assets.spec.ts | 4 +++- playground/hmr/__tests__/hmr.spec.ts | 13 +++++++++++++ playground/hmr/hmr.ts | 11 +++++++++++ playground/hmr/index.html | 1 + playground/hmr/logo.svg | 3 +++ 9 files changed, 48 insertions(+), 10 deletions(-) create mode 100644 playground/hmr/logo.svg diff --git a/packages/vite/src/node/plugins/asset.ts b/packages/vite/src/node/plugins/asset.ts index 9a91234f9..ce559f419 100644 --- a/packages/vite/src/node/plugins/asset.ts +++ b/packages/vite/src/node/plugins/asset.ts @@ -191,7 +191,9 @@ export function assetPlugin(config: ResolvedConfig): Plugin { id = id.replace(urlRE, '$1').replace(unnededFinalQueryCharRE, '') const url = await fileToUrl(id, config, this) - return `export default ${JSON.stringify(url)}` + return `export default ${JSON.stringify( + config.command === 'serve' ? `${url}?t=${Date.now()}` : url, + )}` }, renderChunk(code, chunk, opts) { diff --git a/playground/assets/__tests__/assets.spec.ts b/playground/assets/__tests__/assets.spec.ts index 416b49988..224c4ae9e 100644 --- a/playground/assets/__tests__/assets.spec.ts +++ b/playground/assets/__tests__/assets.spec.ts @@ -293,7 +293,9 @@ describe('svg fragments', () => { test('from js import', async () => { const img = await page.$('.svg-frag-import') - expect(await img.getAttribute('src')).toMatch(/svg#icon-heart-view$/) + expect(await img.getAttribute('src')).toMatch( + isBuild ? /svg#icon-heart-view$/ : /svg\?t=\d+#icon-heart-view$/, + ) }) }) @@ -321,11 +323,11 @@ test('?url import', async () => { test('?url import on css', async () => { const src = readFile('css/icons.css') const txt = await page.textContent('.url-css') - expect(txt).toEqual( - isBuild - ? `data:text/css;base64,${Buffer.from(src).toString('base64')}` - : '/foo/bar/css/icons.css', - ) + isBuild + ? expect(txt).toEqual( + `data:text/css;base64,${Buffer.from(src).toString('base64')}`, + ) + : expect(txt).toMatch(/^\/foo\/bar\/css\/icons.css\?t=\d+$/) }) describe('unicode url', () => { diff --git a/playground/assets/__tests__/relative-base/relative-base-assets.spec.ts b/playground/assets/__tests__/relative-base/relative-base-assets.spec.ts index 196cac0a3..691c9800e 100644 --- a/playground/assets/__tests__/relative-base/relative-base-assets.spec.ts +++ b/playground/assets/__tests__/relative-base/relative-base-assets.spec.ts @@ -179,7 +179,9 @@ describe('svg fragments', () => { test('from js import', async () => { const img = await page.$('.svg-frag-import') - expect(await img.getAttribute('src')).toMatch(/svg#icon-heart-view$/) + expect(await img.getAttribute('src')).toMatch( + isBuild ? /svg#icon-heart-view$/ : /svg\?t=\d+#icon-heart-view$/, + ) }) }) diff --git a/playground/assets/__tests__/runtime-base/runtime-base-assets.spec.ts b/playground/assets/__tests__/runtime-base/runtime-base-assets.spec.ts index 12412d00e..a7d0ad9c1 100644 --- a/playground/assets/__tests__/runtime-base/runtime-base-assets.spec.ts +++ b/playground/assets/__tests__/runtime-base/runtime-base-assets.spec.ts @@ -179,7 +179,9 @@ describe('svg fragments', () => { test('from js import', async () => { const img = await page.$('.svg-frag-import') - expect(await img.getAttribute('src')).toMatch(/svg#icon-heart-view$/) + expect(await img.getAttribute('src')).toMatch( + isBuild ? /svg#icon-heart-view$/ : /svg\?t=\d+#icon-heart-view$/, + ) }) }) diff --git a/playground/assets/__tests__/url-base/url-base-assets.spec.ts b/playground/assets/__tests__/url-base/url-base-assets.spec.ts index c5c9f97d8..633ade90b 100644 --- a/playground/assets/__tests__/url-base/url-base-assets.spec.ts +++ b/playground/assets/__tests__/url-base/url-base-assets.spec.ts @@ -173,7 +173,9 @@ describe('svg fragments', () => { test('from js import', async () => { const img = await page.$('.svg-frag-import') - expect(await img.getAttribute('src')).toMatch(/svg#icon-heart-view$/) + expect(await img.getAttribute('src')).toMatch( + isBuild ? /svg#icon-heart-view$/ : /svg\?t=\d+#icon-heart-view$/, + ) }) }) diff --git a/playground/hmr/__tests__/hmr.spec.ts b/playground/hmr/__tests__/hmr.spec.ts index 4c6caf5ab..1523b6b8f 100644 --- a/playground/hmr/__tests__/hmr.spec.ts +++ b/playground/hmr/__tests__/hmr.spec.ts @@ -809,4 +809,17 @@ if (import.meta.hot) { ) await untilUpdated(() => el.textContent(), 'cc') }) + + test('assets HMR', async () => { + await page.goto(viteTestUrl) + const el = await page.$('#logo') + await untilBrowserLogAfter( + () => + editFile('logo.svg', (code) => + code.replace('height="30px"', 'height="40px"'), + ), + /Logo updated/, + ) + await untilUpdated(() => el.evaluate((it) => `${it.clientHeight}`), '40') + }) } diff --git a/playground/hmr/hmr.ts b/playground/hmr/hmr.ts index 6273f071d..6267a588b 100644 --- a/playground/hmr/hmr.ts +++ b/playground/hmr/hmr.ts @@ -4,12 +4,14 @@ import './importing-updated' import './invalidation/parent' import './file-delete-restore' import './optional-chaining/parent' +import logo from './logo.svg' export const foo = 1 text('.app', foo) text('.dep', depFoo) text('.nested', nestedFoo) text('.virtual', virtual) +setLogo(logo) const btn = document.querySelector('.virtual-update') as HTMLButtonElement btn.onclick = () => { @@ -34,6 +36,11 @@ if (import.meta.hot) { text('.nested', newNestedFoo) } + import.meta.hot.accept('./logo.svg', (newUrl) => { + setLogo(newUrl.default) + console.log('Logo updated', newUrl.default) + }) + import.meta.hot.accept('./hmrDep', ({ foo, nestedFoo }) => { handleDep('single dep', foo, nestedFoo) }) @@ -121,6 +128,10 @@ function text(el, text) { document.querySelector(el).textContent = text } +function setLogo(src) { + ;(document.querySelector('#logo') as HTMLImageElement).src = src +} + function removeCb({ msg }) { text('.toRemove', msg) import.meta.hot.off('custom:remove', removeCb) diff --git a/playground/hmr/index.html b/playground/hmr/index.html index 99df28951..53e3390ac 100644 --- a/playground/hmr/index.html +++ b/playground/hmr/index.html @@ -33,3 +33,4 @@
+ diff --git a/playground/hmr/logo.svg b/playground/hmr/logo.svg new file mode 100644 index 000000000..a85344da4 --- /dev/null +++ b/playground/hmr/logo.svg @@ -0,0 +1,3 @@ + + Vite +