From 7089528b7c740de7fafa715c01c368271afc8e6b Mon Sep 17 00:00:00 2001
From: sun0day
Date: Thu, 4 May 2023 12:39:41 +0800
Subject: [PATCH] fix(assetImportMetaUrl): reserve dynamic template literal
query params (#13034)
---
.../src/node/plugins/assetImportMetaUrl.ts | 18 ++++++++++++++--
playground/assets/__tests__/assets.spec.ts | 11 ++++++++++
playground/assets/index.html | 21 +++++++++++++++++++
3 files changed, 48 insertions(+), 2 deletions(-)
diff --git a/packages/vite/src/node/plugins/assetImportMetaUrl.ts b/packages/vite/src/node/plugins/assetImportMetaUrl.ts
index 6872de5249e014..d16b1ad7540b64 100644
--- a/packages/vite/src/node/plugins/assetImportMetaUrl.ts
+++ b/packages/vite/src/node/plugins/assetImportMetaUrl.ts
@@ -5,6 +5,7 @@ import type { Plugin } from '../plugin'
import type { ResolvedConfig } from '../config'
import type { ResolveFn } from '../'
import {
+ injectQuery,
isParentDirectory,
normalizePath,
slash,
@@ -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)
@@ -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.
@@ -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
}
diff --git a/playground/assets/__tests__/assets.spec.ts b/playground/assets/__tests__/assets.spec.ts
index 3aa3a9ab3189dd..29d56820c6c4bf 100644
--- a/playground/assets/__tests__/assets.spec.ts
+++ b/playground/assets/__tests__/assets.spec.ts
@@ -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,
diff --git a/playground/assets/index.html b/playground/assets/index.html
index 57caa90f4f552d..b9e857398b6c35 100644
--- a/playground/assets/index.html
+++ b/playground/assets/index.html
@@ -221,6 +221,16 @@ new URL(`./${dynamic}`, import.meta.url,) (with comma)
+new URL(`./${dynamic}?abc`, import.meta.url)
+
+
+
+
+
+
+
+
+
new URL(`non-existent`, import.meta.url)
@@ -432,6 +442,17 @@
assets in noscript
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