Skip to content

Commit

Permalink
fix(assetImportMetaUrl): reserve dynamic template literal query params (
Browse files Browse the repository at this point in the history
  • Loading branch information
sun0day committed May 4, 2023
1 parent 21dd28d commit 7089528
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 2 deletions.
18 changes: 16 additions & 2 deletions packages/vite/src/node/plugins/assetImportMetaUrl.ts
Expand Up @@ -5,6 +5,7 @@ import type { Plugin } from '../plugin'
import type { ResolvedConfig } from '../config'
import type { ResolveFn } from '../'
import {
injectQuery,
isParentDirectory,
normalizePath,
slash,
Expand Down Expand Up @@ -55,7 +56,12 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin {

// potential dynamic template string
if (rawUrl[0] === '`' && rawUrl.includes('${')) {
const ast = this.parse(rawUrl)
let [pureUrl, queryString = ''] = rawUrl.split('?')
if (queryString) {
pureUrl += '`'
queryString = '?' + queryString.slice(0, -1)
}
const ast = this.parse(pureUrl)
const templateLiteral = (ast as any).body[0].expression
if (templateLiteral.expressions.length) {
const pattern = buildGlobPattern(templateLiteral)
Expand All @@ -65,6 +71,12 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
continue
}

const globOptions = {
eager: true,
import: 'default',
// A hack to allow 'as' & 'query' exist at the same time
query: injectQuery(queryString, 'url'),
}
// Note: native import.meta.url is not supported in the baseline
// target so we use the global location here. It can be
// window.location or self.location in case it is used in a Web Worker.
Expand All @@ -74,7 +86,9 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
index + exp.length,
`new URL((import.meta.glob(${JSON.stringify(
pattern,
)}, { eager: true, import: 'default', as: 'url' }))[${rawUrl}], self.location)`,
)}, ${JSON.stringify(
globOptions,
)}))[${pureUrl}], self.location)`,
)
continue
}
Expand Down
11 changes: 11 additions & 0 deletions playground/assets/__tests__/assets.spec.ts
Expand Up @@ -324,6 +324,17 @@ test('new URL(`${dynamic}`, import.meta.url)', async () => {
)
})

test('new URL(`./${dynamic}?abc`, import.meta.url)', async () => {
expect(await page.textContent('.dynamic-import-meta-url-1-query')).toMatch(
isBuild ? 'data:image/png;base64' : '/foo/nested/icon.png?abc',
)
expect(await page.textContent('.dynamic-import-meta-url-2-query')).toMatch(
isBuild
? /\/foo\/assets\/asset-\w{8}\.png\?abc/
: '/foo/nested/asset.png?abc',
)
})

test('new URL(`non-existent`, import.meta.url)', async () => {
expect(await page.textContent('.non-existent-import-meta-url')).toMatch(
new URL('non-existent', page.url()).pathname,
Expand Down
21 changes: 21 additions & 0 deletions playground/assets/index.html
Expand Up @@ -221,6 +221,16 @@ <h2>new URL(`./${dynamic}`, import.meta.url,) (with comma)</h2>
<code class="dynamic-import-meta-url-2-comma"></code>
</p>

<h2>new URL(`./${dynamic}?abc`, import.meta.url)</h2>
<p>
<img class="dynamic-import-meta-url-img-1-query" />
<code class="dynamic-import-meta-url-1-query"></code>
</p>
<p>
<img class="dynamic-import-meta-url-img-2-query" />
<code class="dynamic-import-meta-url-2-query"></code>
</p>

<h2>new URL(`non-existent`, import.meta.url)</h2>
<p>
<code class="non-existent-import-meta-url"></code>
Expand Down Expand Up @@ -432,6 +442,17 @@ <h3>assets in noscript</h3>
testDynamicImportMetaUrlWithComma('icon', 1)
testDynamicImportMetaUrlWithComma('asset', 2)

function testDynamicImportMetaUrlWithQuery(name, i) {
// prettier-ignore
const metaUrl = new URL(`./nested/${name}.png?abc`, import.meta.url,)
text(`.dynamic-import-meta-url-${i}-query`, metaUrl)
document.querySelector(`.dynamic-import-meta-url-img-${i}-query`).src =
metaUrl
}

testDynamicImportMetaUrlWithQuery('icon', 1)
testDynamicImportMetaUrlWithQuery('asset', 2)

{
const name = 'test'
const js = new URL(`./nested/${name}.js`, import.meta.url).href
Expand Down

0 comments on commit 7089528

Please sign in to comment.