diff --git a/packages/vite/src/node/plugins/asset.ts b/packages/vite/src/node/plugins/asset.ts index 0403009d4b69c4..13b2963e77e841 100644 --- a/packages/vite/src/node/plugins/asset.ts +++ b/packages/vite/src/node/plugins/asset.ts @@ -239,6 +239,13 @@ export function getAssetFilename( return assetHashToFilenameMap.get(config)?.get(hash) } +export function getPublicAssetFilename( + hash: string, + config: ResolvedConfig +): string | undefined { + return publicAssetUrlCache.get(config)?.get(hash) +} + export function resolveAssetFileNames( config: ResolvedConfig ): string | ((chunkInfo: PreRenderedAsset) => string) { diff --git a/packages/vite/src/node/plugins/html.ts b/packages/vite/src/node/plugins/html.ts index 5287e6e5208ab5..6dbb5717be66a6 100644 --- a/packages/vite/src/node/plugins/html.ts +++ b/packages/vite/src/node/plugins/html.ts @@ -34,6 +34,8 @@ import { assetUrlRE, checkPublicFile, getAssetFilename, + getPublicAssetFilename, + publicAssetUrlRE, urlToBuiltUrl } from './asset' import { isCSSRequest } from './css' @@ -606,13 +608,16 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin { for (const [id, html] of processedHtml) { const relativeUrlPath = path.posix.relative(config.root, id) const assetsBase = getBaseInHTML(relativeUrlPath, config) - const toOutputAssetFilePath = (filename: string) => { + const toOutputFilePath = ( + filename: string, + type: 'asset' | 'public' + ) => { if (isExternalUrl(filename)) { return filename } else { return toOutputFilePathInHtml( filename, - 'asset', + type, relativeUrlPath, 'html', config, @@ -621,6 +626,12 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin { } } + const toOutputAssetFilePath = (filename: string) => + toOutputFilePath(filename, 'asset') + + const toOutputPublicAssetFilePath = (filename: string) => + toOutputFilePath(filename, 'public') + const isAsync = isAsyncScriptMap.get(config)!.get(id)! let result = html @@ -709,6 +720,14 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin { ) }) + result = result.replace(publicAssetUrlRE, (_, fileHash) => { + return normalizePath( + toOutputPublicAssetFilePath( + getPublicAssetFilename(fileHash, config)! + ) + ) + }) + if (chunk && canInlineEntry) { // all imports from entry have been inlined to html, prevent rollup from outputting it delete bundle[chunk.fileName] diff --git a/playground/assets/__tests__/assets.spec.ts b/playground/assets/__tests__/assets.spec.ts index c815714469b63b..3e5caf56205664 100644 --- a/playground/assets/__tests__/assets.spec.ts +++ b/playground/assets/__tests__/assets.spec.ts @@ -364,3 +364,14 @@ test('relative path in html asset', async () => { expect(await page.textContent('.relative-js')).toMatch('hello') expect(await getColor('.relative-css')).toMatch('red') }) + +test('url() contains file in publicDir, in +

+ inline style +

+

use style class

@import