From 5aa4769a588fbf7ee9a5000ab3243b60b7386e89 Mon Sep 17 00:00:00 2001 From: Kyle Herock Date: Mon, 2 May 2022 22:57:10 -0400 Subject: [PATCH] perf: optimize URL constructors with relative paths --- .../src/node/plugins/assetImportMetaUrl.ts | 63 ++++++++++++------- .../src/node/plugins/workerImportMetaUrl.ts | 21 +++++-- playground/worker/worker/main-module.js | 2 +- 3 files changed, 59 insertions(+), 27 deletions(-) diff --git a/packages/vite/src/node/plugins/assetImportMetaUrl.ts b/packages/vite/src/node/plugins/assetImportMetaUrl.ts index aad3252f3cfb71..de946614620866 100644 --- a/packages/vite/src/node/plugins/assetImportMetaUrl.ts +++ b/packages/vite/src/node/plugins/assetImportMetaUrl.ts @@ -1,9 +1,15 @@ +import path from 'node:path' import MagicString from 'magic-string' import { stripLiteral } from 'strip-literal' import type { Plugin } from '../plugin' import type { ResolvedConfig } from '../config' import type { ResolveFn } from '../' -import { isParentDirectory, normalizePath, transformStableResult } from '../utils' +import { + isParentDirectory, + normalizePath, + slash, + transformStableResult +} from '../utils' import { fileToUrl } from './asset' import { preloadHelperId } from './importAnalysisBuild' @@ -18,6 +24,7 @@ import { preloadHelperId } from './importAnalysisBuild' * ``` */ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin { + const normalizedPublicDir = normalizePath(config.publicDir) let assetResolver: ResolveFn return { @@ -65,31 +72,45 @@ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin { } const url = rawUrl.slice(1, -1) - assetResolver ??= config.createResolver({ - root: config.publicDir, - extensions: [], - mainFields: [], - tryIndex: false, - preferRelative: true - }) - const resolved = await assetResolver(url, id) - if (!resolved) { + let file: string | undefined + if (url.startsWith('.')) { + file = slash(path.resolve(path.dirname(id), url)) + } else { + assetResolver ??= config.createResolver({ + extensions: [], + mainFields: [], + tryIndex: false, + preferRelative: true + }) + file = await assetResolver(url, id) + file ??= url.startsWith('/') + ? slash(path.join(config.publicDir, url)) + : slash(path.resolve(path.dirname(id), url)) + } + + // Get final asset URL. If the file does not exist, + // we fall back to the initial URL and let it resolve in runtime + let builtUrl: string | undefined + if (file) { + try { + if (isParentDirectory(normalizedPublicDir, file)) { + const publicPath = + '/' + path.posix.relative(normalizedPublicDir, file) + builtUrl = await fileToUrl(publicPath, config, this) + } else { + builtUrl = await fileToUrl(file, config, this) + } + } catch { + // do nothing, we'll log a warning after this + } + } + if (!builtUrl) { const rawExp = code.slice(index, index + exp.length) config.logger.warnOnce( `\n${rawExp} doesn't exist at build time, it will remain unchanged to be resolved at runtime` ) + builtUrl = url } - // Get final asset URL. If the file does not exist, - // we fall back to the initial URL and let it resolve in runtime - const builtUrl = resolved - ? await fileToUrl( - isParentDirectory(normalizePath(config.publicDir), resolved) - ? url - : resolved, - config, - this - ) - : url s.overwrite( index, index + exp.length, diff --git a/packages/vite/src/node/plugins/workerImportMetaUrl.ts b/packages/vite/src/node/plugins/workerImportMetaUrl.ts index 95c721d5953593..ac1ee0fb545982 100644 --- a/packages/vite/src/node/plugins/workerImportMetaUrl.ts +++ b/packages/vite/src/node/plugins/workerImportMetaUrl.ts @@ -1,3 +1,4 @@ +import path from 'node:path' import JSON5 from 'json5' import MagicString from 'magic-string' import type { RollupError } from 'rollup' @@ -8,6 +9,7 @@ import { cleanUrl, injectQuery, parseRequest, + slash, transformStableResult } from '../utils' import { getDepsOptimizer } from '../optimizer' @@ -113,11 +115,20 @@ export function workerImportMetaUrlPlugin(config: ResolvedConfig): Plugin { index + allExp.length ) const url = rawUrl.slice(1, -1) - workerResolver ??= config.createResolver({ - tryIndex: false, - preferRelative: true - }) - const file = (await workerResolver(url, id)) ?? url + let file: string | undefined + if (url.startsWith('.')) { + file = path.resolve(path.dirname(id), url) + } else { + workerResolver ??= config.createResolver({ + extensions: [], + tryIndex: false, + preferRelative: true + }) + file = await workerResolver(url, id) + file ??= url.startsWith('/') + ? slash(path.join(config.publicDir, url)) + : slash(path.resolve(path.dirname(id), url)) + } let builtUrl: string if (isBuild) { diff --git a/playground/worker/worker/main-module.js b/playground/worker/worker/main-module.js index 1fbd0a689d73f9..913b431a7c759a 100644 --- a/playground/worker/worker/main-module.js +++ b/playground/worker/worker/main-module.js @@ -67,7 +67,7 @@ w.addEventListener('message', (ev) => // url import worker with alias path const wResolve = new Worker( - new URL('@/url-worker', import.meta.url), + new URL('@/url-worker.js', import.meta.url), /* @vite-ignore */ workerOptions ) wResolve.addEventListener('message', (ev) =>