From eeb0617bedee6352695b69ecf8a3dc4b0572c59e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=BF=A0=20/=20green?=
Date: Wed, 10 May 2023 21:58:02 +0900
Subject: [PATCH] fix: call `tryFsResolve` for relative `new URL(foo,
import.meta.url)` (#13142)
---
.../vite/src/node/plugins/assetImportMetaUrl.ts | 13 +++++++++++++
packages/vite/src/node/plugins/resolve.ts | 2 +-
.../vite/src/node/plugins/workerImportMetaUrl.ts | 13 +++++++++++++
playground/assets/__tests__/assets.spec.ts | 9 +++++++++
playground/assets/index.html | 15 +++++++++++++++
playground/worker/__tests__/es/es-worker.spec.ts | 5 +++++
.../worker/__tests__/iife/iife-worker.spec.ts | 5 +++++
playground/worker/index.html | 6 ++++++
playground/worker/worker/main-module.js | 9 +++++++++
9 files changed, 76 insertions(+), 1 deletion(-)
diff --git a/packages/vite/src/node/plugins/assetImportMetaUrl.ts b/packages/vite/src/node/plugins/assetImportMetaUrl.ts
index d16b1ad7540b64..c20abbdc953406 100644
--- a/packages/vite/src/node/plugins/assetImportMetaUrl.ts
+++ b/packages/vite/src/node/plugins/assetImportMetaUrl.ts
@@ -14,6 +14,8 @@ import {
import { CLIENT_ENTRY } from '../constants'
import { fileToUrl } from './asset'
import { preloadHelperId } from './importAnalysisBuild'
+import type { InternalResolveOptions } from './resolve'
+import { tryFsResolve } from './resolve'
/**
* Convert `new URL('./foo.png', import.meta.url)` to its resolved built URL
@@ -29,6 +31,16 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
const normalizedPublicDir = normalizePath(config.publicDir)
let assetResolver: ResolveFn
+ const fsResolveOptions: InternalResolveOptions = {
+ ...config.resolve,
+ root: config.root,
+ isProduction: config.isProduction,
+ isBuild: config.command === 'build',
+ packageCache: config.packageCache,
+ ssrConfig: config.ssr,
+ asSrc: true,
+ }
+
return {
name: 'vite:asset-import-meta-url',
async transform(code, id, options) {
@@ -98,6 +110,7 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
let file: string | undefined
if (url[0] === '.') {
file = slash(path.resolve(path.dirname(id), url))
+ file = tryFsResolve(file, fsResolveOptions) ?? file
} else {
assetResolver ??= config.createResolver({
extensions: [],
diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts
index c5a0876a0963a4..4b28e810ab2c6e 100644
--- a/packages/vite/src/node/plugins/resolve.ts
+++ b/packages/vite/src/node/plugins/resolve.ts
@@ -498,7 +498,7 @@ function splitFileAndPostfix(path: string) {
return { file, postfix: path.slice(file.length) }
}
-function tryFsResolve(
+export function tryFsResolve(
fsPath: string,
options: InternalResolveOptions,
tryIndex = true,
diff --git a/packages/vite/src/node/plugins/workerImportMetaUrl.ts b/packages/vite/src/node/plugins/workerImportMetaUrl.ts
index 2bda9ab737e273..5e186af64f8648 100644
--- a/packages/vite/src/node/plugins/workerImportMetaUrl.ts
+++ b/packages/vite/src/node/plugins/workerImportMetaUrl.ts
@@ -17,6 +17,8 @@ import type { ResolveFn } from '..'
import type { WorkerType } from './worker'
import { WORKER_FILE_ID, workerFileToUrl } from './worker'
import { fileToUrl } from './asset'
+import type { InternalResolveOptions } from './resolve'
+import { tryFsResolve } from './resolve'
const ignoreFlagRE = /\/\*\s*@vite-ignore\s*\*\//
@@ -99,6 +101,16 @@ export function workerImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
const isBuild = config.command === 'build'
let workerResolver: ResolveFn
+ const fsResolveOptions: InternalResolveOptions = {
+ ...config.resolve,
+ root: config.root,
+ isProduction: config.isProduction,
+ isBuild: config.command === 'build',
+ packageCache: config.packageCache,
+ ssrConfig: config.ssr,
+ asSrc: true,
+ }
+
return {
name: 'vite:worker-import-meta-url',
@@ -143,6 +155,7 @@ export function workerImportMetaUrlPlugin(config: ResolvedConfig): Plugin {
let file: string | undefined
if (url[0] === '.') {
file = path.resolve(path.dirname(id), url)
+ file = tryFsResolve(file, fsResolveOptions) ?? file
} else {
workerResolver ??= config.createResolver({
extensions: [],
diff --git a/playground/assets/__tests__/assets.spec.ts b/playground/assets/__tests__/assets.spec.ts
index 29d56820c6c4bf..d4a16dafde7404 100644
--- a/playground/assets/__tests__/assets.spec.ts
+++ b/playground/assets/__tests__/assets.spec.ts
@@ -312,6 +312,15 @@ test('new URL("/...", import.meta.url)', async () => {
)
})
+test('new URL(..., import.meta.url) without extension', async () => {
+ expect(await page.textContent('.import-meta-url-without-extension')).toMatch(
+ isBuild ? 'data:application/javascript' : 'nested/test.js',
+ )
+ expect(
+ await page.textContent('.import-meta-url-content-without-extension'),
+ ).toContain('export default class')
+})
+
test('new URL(`${dynamic}`, import.meta.url)', async () => {
expect(await page.textContent('.dynamic-import-meta-url-1')).toMatch(
isBuild ? 'data:image/png;base64' : '/foo/nested/icon.png',
diff --git a/playground/assets/index.html b/playground/assets/index.html
index b9e857398b6c35..f8c1f5a515a140 100644
--- a/playground/assets/index.html
+++ b/playground/assets/index.html
@@ -190,6 +190,14 @@ new URL('/...', import.meta.url)
+new URL('...', import.meta.url (without extension))
+
+
+
+
+
+
+
new URL('...', import.meta.url,) (with comma)
@@ -393,6 +401,13 @@ assets in noscript
text('.import-meta-url-base-path', metaUrlBasePath)
document.querySelector('.import-meta-url-base-path-img').src = metaUrlBasePath
+ const metaUrlWithoutExtension = new URL('./nested/test', import.meta.url)
+ text('.import-meta-url-without-extension', metaUrlWithoutExtension)
+ ;(async () => {
+ const res = await fetch(metaUrlWithoutExtension)
+ text('.import-meta-url-content-without-extension', await res.text())
+ })()
+
// prettier-ignore
const metaUrlWithComma = new URL('./nested/asset.png', import.meta.url,)
text('.import-meta-url-comma', metaUrlWithComma)
diff --git a/playground/worker/__tests__/es/es-worker.spec.ts b/playground/worker/__tests__/es/es-worker.spec.ts
index dfa2462f61a551..e20ecede337ff1 100644
--- a/playground/worker/__tests__/es/es-worker.spec.ts
+++ b/playground/worker/__tests__/es/es-worker.spec.ts
@@ -113,6 +113,11 @@ test('module worker', async () => {
'A string',
true,
)
+ await untilUpdated(
+ () => page.textContent('.worker-import-meta-url-without-extension'),
+ 'A string',
+ true,
+ )
await untilUpdated(
() => page.textContent('.shared-worker-import-meta-url'),
'A string',
diff --git a/playground/worker/__tests__/iife/iife-worker.spec.ts b/playground/worker/__tests__/iife/iife-worker.spec.ts
index f3e5f230a9b1ed..b3ec815b78ca22 100644
--- a/playground/worker/__tests__/iife/iife-worker.spec.ts
+++ b/playground/worker/__tests__/iife/iife-worker.spec.ts
@@ -98,6 +98,11 @@ test('module worker', async () => {
/A\sstring.*\/iife\/.+url-worker\.js/,
true,
)
+ await untilUpdated(
+ () => page.textContent('.worker-import-meta-url-without-extension'),
+ 'A string',
+ true,
+ )
await untilUpdated(
() => page.textContent('.shared-worker-import-meta-url'),
'A string',
diff --git a/playground/worker/index.html b/playground/worker/index.html
index ff26fbcbba3206..20e4a99ca69876 100644
--- a/playground/worker/index.html
+++ b/playground/worker/index.html
@@ -56,6 +56,12 @@
+
+ new Worker(new URL('./url-worker', import.meta.url), { type: 'module' })
+ .worker-import-meta-url-without-extension
+
+
+
new SharedWorker(new URL('./url-shared-worker.js', import.meta.url), { type:
'module' })
diff --git a/playground/worker/worker/main-module.js b/playground/worker/worker/main-module.js
index e19f8f4ec3af3a..11180f4e63d379 100644
--- a/playground/worker/worker/main-module.js
+++ b/playground/worker/worker/main-module.js
@@ -90,6 +90,15 @@ wResolve.addEventListener('message', (ev) =>
text('.worker-import-meta-url-resolve', JSON.stringify(ev.data)),
)
+// url import worker without extension
+const wWithoutExt = new Worker(
+ new URL('../url-worker', import.meta.url),
+ /* @vite-ignore */ workerOptions,
+)
+wWithoutExt.addEventListener('message', (ev) =>
+ text('.worker-import-meta-url-without-extension', JSON.stringify(ev.data)),
+)
+
const genWorkerName = () => 'module'
const w2 = new SharedWorker(
new URL('../url-shared-worker.js', import.meta.url),