diff --git a/packages/vite/src/node/plugins/html.ts b/packages/vite/src/node/plugins/html.ts
index 56e328974cd708..b10a2e0cd23a01 100644
--- a/packages/vite/src/node/plugins/html.ts
+++ b/packages/vite/src/node/plugins/html.ts
@@ -328,7 +328,7 @@ function handleParseError(
/**
* Compiles index.html into an entry js module
*/
-export function buildHtmlPlugin(config: ResolvedConfig): Plugin {
+export function htmlPlugin(config: ResolvedConfig): Plugin {
const [preHooks, normalHooks, postHooks] = resolveHtmlTransforms(
config.plugins,
)
@@ -345,9 +345,15 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin {
// Same reason with `htmlInlineProxyPlugin`
isAsyncScriptMap.set(config, new Map())
+ let server: ViteDevServer | undefined
+
return {
name: 'vite:build-html',
+ configureServer(s) {
+ server = s
+ },
+
transform: {
async handler(html, id) {
if (id.endsWith('.html')) {
@@ -356,6 +362,15 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin {
const publicPath = `/${relativeUrlPath}`
const publicBase = getBaseInHTML(relativeUrlPath, config)
+ if (server) {
+ const result = await server.transformIndexHtml(publicPath, html)
+ return {
+ code: '',
+ map: { mappings: '' },
+ meta: { 'vite:build-html': result },
+ }
+ }
+
const publicToRelative = (filename: string) => publicBase + filename
const toOutputPublicFilePath = (url: string) =>
toOutputFilePathInHtml(
diff --git a/packages/vite/src/node/plugins/index.ts b/packages/vite/src/node/plugins/index.ts
index 82d87ab1f621b7..7e7eeb093933ae 100644
--- a/packages/vite/src/node/plugins/index.ts
+++ b/packages/vite/src/node/plugins/index.ts
@@ -11,7 +11,7 @@ import { importAnalysisPlugin } from './importAnalysis'
import { cssAnalysisPlugin, cssPlugin, cssPostPlugin } from './css'
import { assetPlugin } from './asset'
import { clientInjectionsPlugin } from './clientInjections'
-import { buildHtmlPlugin, htmlInlineProxyPlugin } from './html'
+import { htmlInlineProxyPlugin, htmlPlugin } from './html'
import { wasmFallbackPlugin, wasmHelperPlugin } from './wasm'
import { modulePreloadPolyfillPlugin } from './modulePreloadPolyfill'
import { webWorkerPlugin } from './worker'
@@ -79,7 +79,7 @@ export async function resolvePlugins(
wasmFallbackPlugin(),
definePlugin(config),
cssPostPlugin(config),
- isBuild && buildHtmlPlugin(config),
+ htmlPlugin(config),
workerImportMetaUrlPlugin(config),
assetImportMetaUrlPlugin(config),
...buildPlugins.pre,
diff --git a/packages/vite/src/node/server/middlewares/indexHtml.ts b/packages/vite/src/node/server/middlewares/indexHtml.ts
index 22b122bee9ff09..78743092c31fb0 100644
--- a/packages/vite/src/node/server/middlewares/indexHtml.ts
+++ b/packages/vite/src/node/server/middlewares/indexHtml.ts
@@ -129,7 +129,7 @@ const processNodeUrl = (
useSrcSetReplacer: boolean,
config: ResolvedConfig,
htmlPath: string,
- originalUrl?: string,
+ _originalUrl?: string,
server?: ViteDevServer,
isClassicScriptLink?: boolean,
): string => {
@@ -145,26 +145,15 @@ const processNodeUrl = (
// rewrite `./index.js` -> `localhost:5173/a/index.js`.
// rewrite `../index.js` -> `localhost:5173/index.js`.
// rewrite `relative/index.js` -> `localhost:5173/a/relative/index.js`.
- ((url[0] === '.' || isBareRelative(url)) &&
- originalUrl &&
- originalUrl !== '/' &&
- htmlPath === '/index.html')
+ url[0] === '.' ||
+ isBareRelative(url)
) {
- url = path.posix.join(config.base, url)
+ url = path.posix.join(config.base, path.posix.dirname(htmlPath), url)
}
let preTransformUrl: string | undefined
-
if (!isClassicScriptLink && shouldPreTransform(url, config)) {
- if (url[0] === '/' && url[1] !== '/') {
- preTransformUrl = url
- } else if (url[0] === '.' || isBareRelative(url)) {
- preTransformUrl = path.posix.join(
- config.base,
- path.posix.dirname(htmlPath),
- url,
- )
- }
+ preTransformUrl = url
}
if (server) {
@@ -369,6 +358,11 @@ const devHtmlHook: IndexHtmlTransformHook = async (
}
}),
)
+
+ const module = await clientModuelGraph.getModuleById(filename)
+ if (module) {
+ clientModuelGraph.invalidateModule(module)
+ }
}
await Promise.all([
@@ -463,9 +457,22 @@ export function indexHtmlMiddleware(
: server.config.preview.headers
try {
- let html = await fsp.readFile(filePath, 'utf-8')
+ let html: string
if (isDev) {
- html = await server.transformIndexHtml(url, html, req.originalUrl)
+ const clientEnv = server.environments.client
+ const resolvedId =
+ await clientEnv.pluginContainer.resolveId(filePath)
+ if (!resolvedId) return next()
+
+ const result = await clientEnv.transformRequest(filePath)
+ if (!result) return next()
+ const moduleInfo = clientEnv.pluginContainer.getModuleInfo(
+ resolvedId.id,
+ )
+ if (!moduleInfo) return next()
+ html = moduleInfo.meta['vite:build-html'] ?? ''
+ } else {
+ html = await fsp.readFile(filePath, 'utf-8')
}
return send(req, res, html, 'html', { headers })
} catch (e) {
diff --git a/playground/assets/__tests__/relative-base/assets-relative-base.spec.ts b/playground/assets/__tests__/relative-base/assets-relative-base.spec.ts
index 576e65bae7cb89..cfd2a9c91b8ccc 100644
--- a/playground/assets/__tests__/relative-base/assets-relative-base.spec.ts
+++ b/playground/assets/__tests__/relative-base/assets-relative-base.spec.ts
@@ -162,7 +162,7 @@ describe('image', () => {
expect(s).toMatch(
isBuild
? /other-assets\/asset-[-\w]{8}\.png \dx/
- : /\.\/nested\/asset\.png \dx/,
+ : /\/nested\/asset\.png \dx/,
)
})
})
diff --git a/playground/assets/__tests__/runtime-base/assets-runtime-base.spec.ts b/playground/assets/__tests__/runtime-base/assets-runtime-base.spec.ts
index 48e982b60e37ac..2a826bc7b6337c 100644
--- a/playground/assets/__tests__/runtime-base/assets-runtime-base.spec.ts
+++ b/playground/assets/__tests__/runtime-base/assets-runtime-base.spec.ts
@@ -157,7 +157,7 @@ describe('image', () => {
expect(s).toMatch(
isBuild
? /other-assets\/asset-[-\w]{8}\.png \dx/
- : /\.\/nested\/asset\.png \dx/,
+ : /\/nested\/asset\.png \dx/,
)
})
})
diff --git a/playground/assets/__tests__/url-base/assets-url-base.spec.ts b/playground/assets/__tests__/url-base/assets-url-base.spec.ts
index 1e143c9b772fba..9587fd66bc96d4 100644
--- a/playground/assets/__tests__/url-base/assets-url-base.spec.ts
+++ b/playground/assets/__tests__/url-base/assets-url-base.spec.ts
@@ -151,7 +151,7 @@ describe('image', () => {
expect(s).toMatch(
isBuild
? /other-assets\/asset-[-\w]{8}\.png \dx/
- : /\.\/nested\/asset\.png \dx/,
+ : /\/nested\/asset\.png \dx/,
)
})
})