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