mirror of
https://github.com/vitejs/vite.git
synced 2024-11-22 07:09:05 +00:00
fix: srcset handling in html (#6419)
This commit is contained in:
parent
c85e51aaea
commit
a0ee4ffeab
@ -27,7 +27,8 @@ import {
|
||||
ensureWatchedFile,
|
||||
fsPathFromId,
|
||||
injectQuery,
|
||||
normalizePath
|
||||
normalizePath,
|
||||
processSrcSetSync
|
||||
} from '../../utils'
|
||||
import type { ModuleGraph } from '../moduleGraph'
|
||||
|
||||
@ -92,18 +93,23 @@ const processNodeUrl = (
|
||||
originalUrl !== '/' &&
|
||||
htmlPath === '/index.html'
|
||||
) {
|
||||
// #3230 if some request url (localhost:5173/a/b) return to fallback html, the relative assets
|
||||
const replacer = (url: string) =>
|
||||
path.posix.join(
|
||||
config.base,
|
||||
path.posix.relative(originalUrl, config.base),
|
||||
url.slice(1)
|
||||
)
|
||||
|
||||
// #3230 if some request url (localhost:3000/a/b) return to fallback html, the relative assets
|
||||
// path will add `/a/` prefix, it will caused 404.
|
||||
// rewrite before `./index.js` -> `localhost:5173/a/index.js`.
|
||||
// rewrite after `../index.js` -> `localhost:5173/index.js`.
|
||||
s.overwrite(
|
||||
node.value!.loc.start.offset,
|
||||
node.value!.loc.end.offset,
|
||||
`"${path.posix.join(
|
||||
path.posix.relative(originalUrl, '/'),
|
||||
url.slice(1)
|
||||
)}"`,
|
||||
{ contentOnly: true }
|
||||
node.name === 'srcset'
|
||||
? `"${processSrcSetSync(url, ({ url }) => replacer(url))}"`
|
||||
: `"${replacer(url)}"`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -560,11 +560,16 @@ interface ImageCandidate {
|
||||
}
|
||||
const escapedSpaceCharacters = /( |\\t|\\n|\\f|\\r)+/g
|
||||
const imageSetUrlRE = /^(?:[\w\-]+\(.*?\)|'.*?'|".*?"|\S*)/
|
||||
export async function processSrcSet(
|
||||
srcs: string,
|
||||
replacer: (arg: ImageCandidate) => Promise<string>
|
||||
): Promise<string> {
|
||||
const imageCandidates: ImageCandidate[] = splitSrcSet(srcs)
|
||||
function reduceSrcset(ret: { url: string; descriptor: string }[]) {
|
||||
return ret.reduce((prev, { url, descriptor }, index) => {
|
||||
descriptor ??= ''
|
||||
return (prev +=
|
||||
url + ` ${descriptor}${index === ret.length - 1 ? '' : ', '}`)
|
||||
}, '')
|
||||
}
|
||||
|
||||
function splitSrcSetDescriptor(srcs: string): ImageCandidate[] {
|
||||
return splitSrcSet(srcs)
|
||||
.map((s) => {
|
||||
const src = s.replace(escapedSpaceCharacters, ' ').trim()
|
||||
const [url] = imageSetUrlRE.exec(src) || []
|
||||
@ -575,21 +580,30 @@ export async function processSrcSet(
|
||||
}
|
||||
})
|
||||
.filter(({ url }) => !!url)
|
||||
}
|
||||
|
||||
const ret = await Promise.all(
|
||||
imageCandidates.map(async ({ url, descriptor }) => {
|
||||
return {
|
||||
url: await replacer({ url, descriptor }),
|
||||
descriptor
|
||||
}
|
||||
})
|
||||
export function processSrcSet(
|
||||
srcs: string,
|
||||
replacer: (arg: ImageCandidate) => Promise<string>
|
||||
): Promise<string> {
|
||||
return Promise.all(
|
||||
splitSrcSetDescriptor(srcs).map(async ({ url, descriptor }) => ({
|
||||
url: await replacer({ url, descriptor }),
|
||||
descriptor
|
||||
}))
|
||||
).then((ret) => reduceSrcset(ret))
|
||||
}
|
||||
|
||||
export function processSrcSetSync(
|
||||
srcs: string,
|
||||
replacer: (arg: ImageCandidate) => string
|
||||
): string {
|
||||
return reduceSrcset(
|
||||
splitSrcSetDescriptor(srcs).map(({ url, descriptor }) => ({
|
||||
url: replacer({ url, descriptor }),
|
||||
descriptor
|
||||
}))
|
||||
)
|
||||
|
||||
return ret.reduce((prev, { url, descriptor }, index) => {
|
||||
descriptor ??= ''
|
||||
return (prev +=
|
||||
url + ` ${descriptor}${index === ret.length - 1 ? '' : ', '}`)
|
||||
}, '')
|
||||
}
|
||||
|
||||
function splitSrcSet(srcs: string) {
|
||||
|
@ -192,7 +192,7 @@ describe('image', () => {
|
||||
expect(s).toMatch(
|
||||
isBuild
|
||||
? /\/foo\/assets\/asset\.\w{8}\.png \d{1}x/
|
||||
: /\.\/nested\/asset\.png \d{1}x/
|
||||
: /\/foo\/nested\/asset\.png \d{1}x/
|
||||
)
|
||||
})
|
||||
})
|
||||
|
10
playground/env/__tests__/env.spec.ts
vendored
10
playground/env/__tests__/env.spec.ts
vendored
@ -3,7 +3,7 @@ import { isBuild, page } from '~utils'
|
||||
const mode = isBuild ? `production` : `development`
|
||||
|
||||
test('base', async () => {
|
||||
expect(await page.textContent('.base')).toBe('/')
|
||||
expect(await page.textContent('.base')).toBe('/env/')
|
||||
})
|
||||
|
||||
test('mode', async () => {
|
||||
@ -46,9 +46,15 @@ test('env object', async () => {
|
||||
VITE_EFFECTIVE_MODE_FILE_NAME: `.env.${mode}`,
|
||||
CUSTOM_PREFIX_ENV_VARIABLE: '1',
|
||||
VITE_CUSTOM_ENV_VARIABLE: '1',
|
||||
BASE_URL: '/',
|
||||
BASE_URL: '/env/',
|
||||
MODE: mode,
|
||||
DEV: !isBuild,
|
||||
PROD: isBuild
|
||||
})
|
||||
})
|
||||
|
||||
if (!isBuild) {
|
||||
test('relative url import script return import.meta.url', async () => {
|
||||
expect(await page.textContent('.url')).toMatch('/env/index.js')
|
||||
})
|
||||
}
|
||||
|
2
playground/env/index.html
vendored
2
playground/env/index.html
vendored
@ -14,6 +14,7 @@
|
||||
<p>import.meta.env.VITE_INLINE: <code class="inline"></code></p>
|
||||
<p>process.env.NODE_ENV: <code class="node-env"></code></p>
|
||||
<p>import.meta.env: <span class="pre env-object"></span></p>
|
||||
<p>import.meta.url: <span class="pre url"></span></p>
|
||||
|
||||
<script type="module">
|
||||
text('.base', import.meta.env.BASE_URL)
|
||||
@ -31,6 +32,7 @@
|
||||
document.querySelector(el).textContent = text
|
||||
}
|
||||
</script>
|
||||
<script type="module" src="./index.js"></script>
|
||||
|
||||
<style>
|
||||
.pre {
|
||||
|
5
playground/env/index.js
vendored
Normal file
5
playground/env/index.js
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
text('.url', import.meta.url)
|
||||
|
||||
function text(el, text) {
|
||||
document.querySelector(el).textContent = text
|
||||
}
|
6
playground/env/vite.config.js
vendored
6
playground/env/vite.config.js
vendored
@ -1,5 +1,9 @@
|
||||
const { defineConfig } = require('vite')
|
||||
|
||||
module.exports = defineConfig({
|
||||
envPrefix: ['VITE_', 'CUSTOM_PREFIX_']
|
||||
base: '/env/',
|
||||
envPrefix: ['VITE_', 'CUSTOM_PREFIX_'],
|
||||
build: {
|
||||
outDir: 'dist/env'
|
||||
}
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user