From c268cfaf0fdb0c82db22fcc67b790c00b2c248ac Mon Sep 17 00:00:00 2001 From: patak Date: Thu, 30 Mar 2023 20:07:50 +0200 Subject: [PATCH] perf: module graph url shortcuts (#12635) --- .../vite/src/node/plugins/importAnalysis.ts | 2 +- packages/vite/src/node/server/moduleGraph.ts | 66 ++++++++++++++++++- .../vite/src/node/server/transformRequest.ts | 4 +- 3 files changed, 67 insertions(+), 5 deletions(-) diff --git a/packages/vite/src/node/plugins/importAnalysis.ts b/packages/vite/src/node/plugins/importAnalysis.ts index c1a7b6403502cb..8ee82040d21e7f 100644 --- a/packages/vite/src/node/plugins/importAnalysis.ts +++ b/packages/vite/src/node/plugins/importAnalysis.ts @@ -694,7 +694,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { const normalizedAcceptedUrls = new Set() for (const { url, start, end } of acceptedUrls) { const [normalized] = await moduleGraph.resolveUrl( - toAbsoluteUrl(markExplicitImport(url)), + toAbsoluteUrl(url), ssr, ) normalizedAcceptedUrls.add(normalized) diff --git a/packages/vite/src/node/server/moduleGraph.ts b/packages/vite/src/node/server/moduleGraph.ts index 4c3b8ad966388a..af254e38b62704 100644 --- a/packages/vite/src/node/server/moduleGraph.ts +++ b/packages/vite/src/node/server/moduleGraph.ts @@ -61,6 +61,15 @@ export class ModuleGraph { fileToModulesMap = new Map>() safeModulesPath = new Set() + /** + * @internal + */ + _unresolvedUrlToModuleMap = new Map() + /** + * @internal + */ + _ssrUnresolvedUrlToModuleMap = new Map() + constructor( private resolveId: ( url: string, @@ -72,7 +81,14 @@ export class ModuleGraph { rawUrl: string, ssr?: boolean, ): Promise { - const [url] = await this.resolveUrl(rawUrl, ssr) + // Quick path, if we already have a module for this rawUrl (even without extension) + rawUrl = removeImportQuery(removeTimestampQuery(rawUrl)) + const mod = this._getUnresolvedUrlToModule(rawUrl, ssr) + if (mod) { + return mod + } + + const [url] = await this._resolveUrl(rawUrl, ssr) return this.urlToModuleMap.get(url) } @@ -220,8 +236,15 @@ export class ModuleGraph { ssr?: boolean, setIsSelfAccepting = true, ): Promise { - const [url, resolvedId, meta] = await this.resolveUrl(rawUrl, ssr) - let mod = this.idToModuleMap.get(resolvedId) + // Quick path, if we already have a module for this rawUrl (even without extension) + rawUrl = removeImportQuery(removeTimestampQuery(rawUrl)) + let mod = this._getUnresolvedUrlToModule(rawUrl, ssr) + if (mod) { + return mod + } + + const [url, resolvedId, meta] = await this._resolveUrl(rawUrl, ssr) + mod = this.idToModuleMap.get(resolvedId) if (!mod) { mod = new ModuleNode(url, setIsSelfAccepting) if (meta) mod.meta = meta @@ -241,6 +264,11 @@ export class ModuleGraph { else if (!this.urlToModuleMap.has(url)) { this.urlToModuleMap.set(url, mod) } + + // Also register the clean url to the module, so that we can short-circuit + // resolving the same url twice + this._setUnresolvedUrlToModule(rawUrl, mod, ssr) + return mod } @@ -275,6 +303,38 @@ export class ModuleGraph { // the same module async resolveUrl(url: string, ssr?: boolean): Promise { url = removeImportQuery(removeTimestampQuery(url)) + const mod = this._getUnresolvedUrlToModule(url, ssr) + if (mod?.id) { + return [mod.url, mod.id, mod.meta] + } + return this._resolveUrl(url, ssr) + } + + /** + * @internal + */ + _getUnresolvedUrlToModule( + url: string, + ssr?: boolean, + ): ModuleNode | undefined { + return ( + ssr ? this._ssrUnresolvedUrlToModuleMap : this._unresolvedUrlToModuleMap + ).get(url) + } + /** + * @internal + */ + _setUnresolvedUrlToModule(url: string, mod: ModuleNode, ssr?: boolean): void { + ;(ssr + ? this._ssrUnresolvedUrlToModuleMap + : this._unresolvedUrlToModuleMap + ).set(url, mod) + } + + /** + * @internal + */ + async _resolveUrl(url: string, ssr?: boolean): Promise { const resolved = await this.resolveId(url, !!ssr) const resolvedId = resolved?.id || url if ( diff --git a/packages/vite/src/node/server/transformRequest.ts b/packages/vite/src/node/server/transformRequest.ts index 82bc7fabc20716..3762c69cfef3b3 100644 --- a/packages/vite/src/node/server/transformRequest.ts +++ b/packages/vite/src/node/server/transformRequest.ts @@ -144,7 +144,9 @@ async function doTransform( // resolve const id = - (await pluginContainer.resolveId(url, undefined, { ssr }))?.id || url + module?.id ?? + (await pluginContainer.resolveId(url, undefined, { ssr }))?.id ?? + url const result = loadAndTransform(id, url, server, options, timestamp)