From 408376d188ed53e7e9bc923fed4df777682ad81f Mon Sep 17 00:00:00 2001
From: ivan
Date: Fri, 28 Apr 2023 16:25:14 +0800
Subject: [PATCH 1/3] fix(assetImportMetaUrl): reserve dynamic template literal
query params
---
.../src/node/plugins/assetImportMetaUrl.ts | 23 +++++++++++++++++--
playground/assets/__tests__/assets.spec.ts | 11 +++++++++
playground/assets/index.html | 21 +++++++++++++++++
3 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/packages/vite/src/node/plugins/assetImportMetaUrl.ts b/packages/vite/src/node/plugins/assetImportMetaUrl.ts
index 6872de5249e014..b2425d68f4615a 100644
--- a/packages/vite/src/node/plugins/assetImportMetaUrl.ts
+++ b/packages/vite/src/node/plugins/assetImportMetaUrl.ts
@@ -1,6 +1,8 @@
import path from 'node:path'
import MagicString from 'magic-string'
import { stripLiteral } from 'strip-literal'
+// import qs from 'node:querystring'
+import { getQuery } from 'ufo'
import type { Plugin } from '../plugin'
import type { ResolvedConfig } from '../config'
import type { ResolveFn } from '../'
@@ -55,7 +57,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.replace(/`$/, '')
+ }
+ const ast = this.parse(pureUrl)
const templateLiteral = (ast as any).body[0].expression
if (templateLiteral.expressions.length) {
const pattern = buildGlobPattern(templateLiteral)
@@ -65,6 +72,16 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
continue
}
+ const query = getQuery(queryString)
+ const globOptions = {
+ eager: true,
+ import: 'default',
+ query: {
+ // A hack to allow 'as' & 'query' exist at the same time
+ url: '',
+ ...query,
+ },
+ }
// 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 +91,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
From bcf7899e1d1839e3afbe9495bcd155d8f27961ec Mon Sep 17 00:00:00 2001
From: ivan
Date: Fri, 28 Apr 2023 16:27:03 +0800
Subject: [PATCH 2/3] chore: remove useless import
---
packages/vite/src/node/plugins/assetImportMetaUrl.ts | 1 -
1 file changed, 1 deletion(-)
diff --git a/packages/vite/src/node/plugins/assetImportMetaUrl.ts b/packages/vite/src/node/plugins/assetImportMetaUrl.ts
index b2425d68f4615a..32438262d47cd7 100644
--- a/packages/vite/src/node/plugins/assetImportMetaUrl.ts
+++ b/packages/vite/src/node/plugins/assetImportMetaUrl.ts
@@ -1,7 +1,6 @@
import path from 'node:path'
import MagicString from 'magic-string'
import { stripLiteral } from 'strip-literal'
-// import qs from 'node:querystring'
import { getQuery } from 'ufo'
import type { Plugin } from '../plugin'
import type { ResolvedConfig } from '../config'
From 354c779046cfcb018160d88322c9b6c065b97d57 Mon Sep 17 00:00:00 2001
From: ivan
Date: Sun, 30 Apr 2023 23:01:18 +0800
Subject: [PATCH 3/3] chore: use injectQuery
---
packages/vite/src/node/plugins/assetImportMetaUrl.ts | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/packages/vite/src/node/plugins/assetImportMetaUrl.ts b/packages/vite/src/node/plugins/assetImportMetaUrl.ts
index 32438262d47cd7..d16b1ad7540b64 100644
--- a/packages/vite/src/node/plugins/assetImportMetaUrl.ts
+++ b/packages/vite/src/node/plugins/assetImportMetaUrl.ts
@@ -1,11 +1,11 @@
import path from 'node:path'
import MagicString from 'magic-string'
import { stripLiteral } from 'strip-literal'
-import { getQuery } from 'ufo'
import type { Plugin } from '../plugin'
import type { ResolvedConfig } from '../config'
import type { ResolveFn } from '../'
import {
+ injectQuery,
isParentDirectory,
normalizePath,
slash,
@@ -59,7 +59,7 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
let [pureUrl, queryString = ''] = rawUrl.split('?')
if (queryString) {
pureUrl += '`'
- queryString = '?' + queryString.replace(/`$/, '')
+ queryString = '?' + queryString.slice(0, -1)
}
const ast = this.parse(pureUrl)
const templateLiteral = (ast as any).body[0].expression
@@ -71,15 +71,11 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
continue
}
- const query = getQuery(queryString)
const globOptions = {
eager: true,
import: 'default',
- query: {
- // A hack to allow 'as' & 'query' exist at the same time
- url: '',
- ...query,
- },
+ // 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