From 50c19ca1c2a0423f3f8ff778c0aa5977bafdcc2f 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 --- .../playground/worker/worker/main-module.js | 2 +- .../src/node/plugins/assetImportMetaUrl.ts | 58 ++++++++++++------- .../src/node/plugins/workerImportMetaUrl.ts | 22 +++++-- 3 files changed, 54 insertions(+), 28 deletions(-) diff --git a/packages/playground/worker/worker/main-module.js b/packages/playground/worker/worker/main-module.js index 756ece90326d0f..bd0cf2e0fd4b0f 100644 --- a/packages/playground/worker/worker/main-module.js +++ b/packages/playground/worker/worker/main-module.js @@ -80,7 +80,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) => diff --git a/packages/vite/src/node/plugins/assetImportMetaUrl.ts b/packages/vite/src/node/plugins/assetImportMetaUrl.ts index a101f7d65e3d74..369bebe8aa7f0e 100644 --- a/packages/vite/src/node/plugins/assetImportMetaUrl.ts +++ b/packages/vite/src/node/plugins/assetImportMetaUrl.ts @@ -1,10 +1,11 @@ import type { Plugin } from '../plugin' import MagicString from 'magic-string' +import path from 'path' import { fileToUrl } from './asset' import type { ResolvedConfig } from '../config' import { emptyString } from '../cleanString' import type { ResolveFn } from '../' -import { isParentDirectory, normalizePath } from '../utils' +import { isParentDirectory, normalizePath, slash } from '../utils' /** * Convert `new URL('./foo.png', import.meta.url)` to its resolved built URL @@ -17,6 +18,7 @@ import { isParentDirectory, normalizePath } from '../utils' * ``` */ export function assetImportMetaUrlPlugin(config: ResolvedConfig): Plugin { + const normalizedPublicDir = normalizePath(config.publicDir) let assetResolver: ResolveFn return { @@ -65,31 +67,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 08f1b989f727fe..5e1115d1fb8c27 100644 --- a/packages/vite/src/node/plugins/workerImportMetaUrl.ts +++ b/packages/vite/src/node/plugins/workerImportMetaUrl.ts @@ -1,8 +1,9 @@ import JSON5 from 'json5' +import path from 'path' import type { ResolvedConfig } from '../config' import type { Plugin } from '../plugin' import { fileToUrl } from './asset' -import { injectQuery } from '../utils' +import { injectQuery, slash } from '../utils' import { workerFileToUrl } from './worker' import { parseRequest } from '../utils' import { ENV_ENTRY, ENV_PUBLIC_PATH } from '../constants' @@ -145,11 +146,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) {