diff --git a/packages/vite/src/node/plugins/asset.ts b/packages/vite/src/node/plugins/asset.ts index 648b34f1d6d6f1..719269c5934290 100644 --- a/packages/vite/src/node/plugins/asset.ts +++ b/packages/vite/src/node/plugins/asset.ts @@ -229,6 +229,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 ac7ac834ff941a..188134d4166442 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' @@ -613,13 +615,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, @@ -628,6 +633,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 @@ -716,6 +727,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 600ea3b0bba971..ceb259102d4031 100644 --- a/playground/assets/__tests__/assets.spec.ts +++ b/playground/assets/__tests__/assets.spec.ts @@ -367,3 +367,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