Skip to content

Commit a2b24ee

Browse files
authored
fix: __VITE_PUBLIC_ASSET__hash__ in HTML (#9247)
1 parent e60368f commit a2b24ee

File tree

4 files changed

+49
-2
lines changed

4 files changed

+49
-2
lines changed

packages/vite/src/node/plugins/asset.ts

+7
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,13 @@ export function getAssetFilename(
229229
return assetHashToFilenameMap.get(config)?.get(hash)
230230
}
231231

232+
export function getPublicAssetFilename(
233+
hash: string,
234+
config: ResolvedConfig
235+
): string | undefined {
236+
return publicAssetUrlCache.get(config)?.get(hash)
237+
}
238+
232239
export function resolveAssetFileNames(
233240
config: ResolvedConfig
234241
): string | ((chunkInfo: PreRenderedAsset) => string) {

packages/vite/src/node/plugins/html.ts

+21-2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ import {
3434
assetUrlRE,
3535
checkPublicFile,
3636
getAssetFilename,
37+
getPublicAssetFilename,
38+
publicAssetUrlRE,
3739
urlToBuiltUrl
3840
} from './asset'
3941
import { isCSSRequest } from './css'
@@ -613,13 +615,16 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin {
613615
for (const [id, html] of processedHtml) {
614616
const relativeUrlPath = path.posix.relative(config.root, id)
615617
const assetsBase = getBaseInHTML(relativeUrlPath, config)
616-
const toOutputAssetFilePath = (filename: string) => {
618+
const toOutputFilePath = (
619+
filename: string,
620+
type: 'asset' | 'public'
621+
) => {
617622
if (isExternalUrl(filename)) {
618623
return filename
619624
} else {
620625
return toOutputFilePathInHtml(
621626
filename,
622-
'asset',
627+
type,
623628
relativeUrlPath,
624629
'html',
625630
config,
@@ -628,6 +633,12 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin {
628633
}
629634
}
630635

636+
const toOutputAssetFilePath = (filename: string) =>
637+
toOutputFilePath(filename, 'asset')
638+
639+
const toOutputPublicAssetFilePath = (filename: string) =>
640+
toOutputFilePath(filename, 'public')
641+
631642
const isAsync = isAsyncScriptMap.get(config)!.get(id)!
632643

633644
let result = html
@@ -716,6 +727,14 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin {
716727
)
717728
})
718729

730+
result = result.replace(publicAssetUrlRE, (_, fileHash) => {
731+
return normalizePath(
732+
toOutputPublicAssetFilePath(
733+
getPublicAssetFilename(fileHash, config)!
734+
)
735+
)
736+
})
737+
719738
if (chunk && canInlineEntry) {
720739
// all imports from entry have been inlined to html, prevent rollup from outputting it
721740
delete bundle[chunk.fileName]

playground/assets/__tests__/assets.spec.ts

+11
Original file line numberDiff line numberDiff line change
@@ -367,3 +367,14 @@ test('relative path in html asset', async () => {
367367
expect(await page.textContent('.relative-js')).toMatch('hello')
368368
expect(await getColor('.relative-css')).toMatch('red')
369369
})
370+
371+
test('url() contains file in publicDir, in <style> tag', async () => {
372+
expect(await getBg('.style-public-assets')).toContain(iconMatch)
373+
})
374+
375+
test.skip('url() contains file in publicDir, as inline style', async () => {
376+
// TODO: To investigate why `await getBg('.inline-style-public') === "url("http://localhost:5173/icon.png")"`
377+
// It supposes to be `url("http://localhost:5173/foo/icon.png")`
378+
// (I built the playground to verify)
379+
expect(await getBg('.inline-style-public')).toContain(iconMatch)
380+
})

playground/assets/index.html

+10
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,16 @@ <h3>base64</h3>
269269
inline style
270270
</p>
271271
<p class="style-base64-assets">use style class</p>
272+
<h3>from publicDir</h3>
273+
<style>
274+
.style-public-assets {
275+
background: url('/icon.png');
276+
}
277+
</style>
278+
<p class="inline-style-public" style="background: url(/icon.png)">
279+
inline style
280+
</p>
281+
<p class="style-public-assets">use style class</p>
272282

273283
<h3 class="import-css">@import</h3>
274284
<style class="style-import">

0 commit comments

Comments
 (0)