New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: inline proxies for virtual html in transformIndexHtml #7993
Changes from all commits
1d34d51
ac05f25
2a764af
ccda81b
a2a0d4f
eb6bfc7
e5eedeb
cced917
b650fd6
1bf08ff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
import fs from 'fs' | ||
import path from 'path' | ||
import MagicString from 'magic-string' | ||
import type { SourceMapInput } from 'rollup' | ||
import type { AttributeNode, ElementNode, TextNode } from '@vue/compiler-dom' | ||
import { NodeTypes } from '@vue/compiler-dom' | ||
import type { Connect } from 'types/connect' | ||
|
@@ -15,7 +16,12 @@ import { | |
} from '../../plugins/html' | ||
import type { ResolvedConfig, ViteDevServer } from '../..' | ||
import { send } from '../send' | ||
import { CLIENT_PUBLIC_PATH, FS_PREFIX } from '../../constants' | ||
import { | ||
CLIENT_PUBLIC_PATH, | ||
FS_PREFIX, | ||
VALID_ID_PREFIX, | ||
NULL_BYTE_PLACEHOLDER | ||
} from '../../constants' | ||
import { | ||
cleanUrl, | ||
fsPathFromId, | ||
|
@@ -108,32 +114,53 @@ const devHtmlHook: IndexHtmlTransformHook = async ( | |
const { config, moduleGraph, watcher } = server! | ||
const base = config.base || '/' | ||
|
||
let proxyModulePath: string | ||
let proxyModuleUrl: string | ||
|
||
const trailingSlash = htmlPath.endsWith('/') | ||
if (!trailingSlash && fs.existsSync(filename)) { | ||
proxyModulePath = htmlPath | ||
proxyModuleUrl = base + htmlPath.slice(1) | ||
} else { | ||
// There are users of vite.transformIndexHtml calling it with url '/' | ||
// for SSR integrations #7993, filename is root for this case | ||
// A user may also use a valid name for a virtual html file | ||
// Mark the path as virtual in both cases so sourcemaps aren't processed | ||
// and ids are properly handled | ||
const validPath = `${htmlPath}${trailingSlash ? 'index.html' : ''}` | ||
proxyModulePath = `\0${validPath}` | ||
proxyModuleUrl = `${VALID_ID_PREFIX}${NULL_BYTE_PLACEHOLDER}${validPath}` | ||
} | ||
|
||
const s = new MagicString(html) | ||
let inlineModuleIndex = -1 | ||
const filePath = cleanUrl(htmlPath) | ||
const proxyCacheUrl = cleanUrl(proxyModulePath).replace( | ||
normalizePath(config.root), | ||
'' | ||
) | ||
const styleUrl: AssetNode[] = [] | ||
|
||
const addInlineModule = (node: ElementNode, ext: 'js') => { | ||
inlineModuleIndex++ | ||
|
||
const url = filePath.replace(normalizePath(config.root), '') | ||
|
||
const contentNode = node.children[0] as TextNode | ||
|
||
const code = contentNode.content | ||
const map = new MagicString(html) | ||
.snip(contentNode.loc.start.offset, contentNode.loc.end.offset) | ||
.generateMap({ hires: true }) | ||
map.sources = [filename] | ||
map.file = filename | ||
|
||
let map: SourceMapInput | undefined | ||
if (!proxyModulePath.startsWith('\0')) { | ||
map = new MagicString(html) | ||
.snip(contentNode.loc.start.offset, contentNode.loc.end.offset) | ||
.generateMap({ hires: true }) | ||
map.sources = [filename] | ||
map.file = filename | ||
poyoho marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
// add HTML Proxy to Map | ||
addToHTMLProxyCache(config, url, inlineModuleIndex, { code, map }) | ||
addToHTMLProxyCache(config, proxyCacheUrl, inlineModuleIndex, { code, map }) | ||
|
||
// inline js module. convert to src="proxy" | ||
const modulePath = `${ | ||
config.base + htmlPath.slice(1) | ||
}?html-proxy&index=${inlineModuleIndex}.${ext}` | ||
const modulePath = `${proxyModuleUrl}?html-proxy&index=${inlineModuleIndex}.${ext}` | ||
|
||
// invalidate the module so the newly cached contents will be served | ||
const module = server?.moduleGraph.getModuleById(modulePath) | ||
|
@@ -190,13 +217,13 @@ const devHtmlHook: IndexHtmlTransformHook = async ( | |
|
||
await Promise.all( | ||
styleUrl.map(async ({ start, end, code }, index) => { | ||
const url = filename + `?html-proxy&${index}.css` | ||
const url = `${proxyModulePath}?html-proxy&index=${index}.css` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The url was missing |
||
|
||
// ensure module in graph after successful load | ||
const mod = await moduleGraph.ensureEntryFromUrl(url, false) | ||
ensureWatchedFile(watcher, mod.file, config.root) | ||
|
||
const result = await server!.pluginContainer.transform(code, url) | ||
const result = await server!.pluginContainer.transform(code, mod.id!) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BTW, |
||
s.overwrite(start, end, result?.code || '') | ||
}) | ||
) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm forcing
'/'
as theurl
here as @brillout described he was doing in vite-plugin-ssr.