From 8b7096c3ceef62e2daf1107fe2937391454c8e73 Mon Sep 17 00:00:00 2001 From: patak Date: Wed, 17 May 2023 13:24:30 +0200 Subject: [PATCH 1/8] fix: ensure module in graph before pretransfom in indexHtml middleware --- .../src/node/server/middlewares/indexHtml.ts | 36 ++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/packages/vite/src/node/server/middlewares/indexHtml.ts b/packages/vite/src/node/server/middlewares/indexHtml.ts index 9c7d6727f6fd9d..5a75e68bbb7649 100644 --- a/packages/vite/src/node/server/middlewares/indexHtml.ts +++ b/packages/vite/src/node/server/middlewares/indexHtml.ts @@ -28,6 +28,8 @@ import { ensureWatchedFile, fsPathFromId, injectQuery, + isDataUrl, + isExternalUrl, joinUrlSegments, normalizePath, processSrcSetSync, @@ -82,6 +84,10 @@ function getHtmlFilename(url: string, server: ViteDevServer) { } } +function shouldPreTransform(url: string, config: ResolvedConfig) { + return !checkPublicFile(url, config) && !isExternalUrl(url) && !isDataUrl(url) +} + const processNodeUrl = ( attr: Token.Attribute, sourceCodeLocation: Token.Location, @@ -104,7 +110,7 @@ const processNodeUrl = ( // prefix with base (dev only, base is never relative) const fullUrl = path.posix.join(devBase, url) overwriteAttrValue(s, sourceCodeLocation, fullUrl) - if (server && !checkPublicFile(url, config)) { + if (server && shouldPreTransform(url, config)) { preTransformRequest(server, fullUrl, devBase) } } else if ( @@ -116,7 +122,7 @@ const processNodeUrl = ( // prefix with base (dev only, base is never relative) const replacer = (url: string) => { const fullUrl = path.posix.join(devBase, url) - if (server && !checkPublicFile(url, config)) { + if (server && shouldPreTransform(url, config)) { preTransformRequest(server, fullUrl, devBase) } return fullUrl @@ -334,14 +340,28 @@ export function indexHtmlMiddleware( } } -function preTransformRequest(server: ViteDevServer, url: string, base: string) { +async function preTransformRequest( + server: ViteDevServer, + url: string, + base: string, +) { if (!server.config.server.preTransformRequests) return url = unwrapId(stripBase(url, base)) - // transform all url as non-ssr as html includes client-side assets only - server.transformRequest(url).catch((e) => { - // Unexpected error, log the issue but avoid an unhandled exception - server.config.logger.error(e.message) - }) + // check if the dep has been hmr updated. If yes, we need to attach + // its last updated timestamp to force the browser to fetch the most + // up-to-date version of this module. + try { + await server.moduleGraph.ensureEntryFromUrl(url) + + // transform all url as non-ssr as html includes client-side assets only + server.transformRequest(url).catch((e) => { + // Unexpected error, log the issue but avoid an unhandled exception + server.config.logger.error(e.message) + }) + } catch (e: any) { + // it's possible that the dep fails to resolve (non-existent import) + // attach location to the missing import + } } From 148d3a1d5c9196c6456d6098e5d5cbae2cd7e9b9 Mon Sep 17 00:00:00 2001 From: patak Date: Wed, 17 May 2023 13:28:38 +0200 Subject: [PATCH 2/8] chore: update --- .../vite/src/node/server/middlewares/indexHtml.ts | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/packages/vite/src/node/server/middlewares/indexHtml.ts b/packages/vite/src/node/server/middlewares/indexHtml.ts index 5a75e68bbb7649..5c128dd2b65fb6 100644 --- a/packages/vite/src/node/server/middlewares/indexHtml.ts +++ b/packages/vite/src/node/server/middlewares/indexHtml.ts @@ -349,19 +349,14 @@ async function preTransformRequest( url = unwrapId(stripBase(url, base)) - // check if the dep has been hmr updated. If yes, we need to attach - // its last updated timestamp to force the browser to fetch the most - // up-to-date version of this module. try { await server.moduleGraph.ensureEntryFromUrl(url) // transform all url as non-ssr as html includes client-side assets only - server.transformRequest(url).catch((e) => { - // Unexpected error, log the issue but avoid an unhandled exception - server.config.logger.error(e.message) - }) + await server.transformRequest(url) } catch (e: any) { // it's possible that the dep fails to resolve (non-existent import) - // attach location to the missing import + // log the issue but avoid an unhandled exception + server.config.logger.error(e.message) } } From 5d9d0cd3b30638a4e3ab5745295cf6c241699717 Mon Sep 17 00:00:00 2001 From: patak Date: Wed, 17 May 2023 14:06:21 +0200 Subject: [PATCH 3/8] fix: transform request cacheKey without timestamp --- packages/vite/src/node/server/transformRequest.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/vite/src/node/server/transformRequest.ts b/packages/vite/src/node/server/transformRequest.ts index b08a01e5d01b9e..575b17ee0bb78e 100644 --- a/packages/vite/src/node/server/transformRequest.ts +++ b/packages/vite/src/node/server/transformRequest.ts @@ -46,7 +46,9 @@ export function transformRequest( server: ViteDevServer, options: TransformOptions = {}, ): Promise { - const cacheKey = (options.ssr ? 'ssr:' : options.html ? 'html:' : '') + url + const cacheKey = + (options.ssr ? 'ssr:' : options.html ? 'html:' : '') + + removeTimestampQuery(url) // This module may get invalidated while we are processing it. For example // when a full page reload is needed after the re-processing of pre-bundled @@ -73,7 +75,7 @@ export function transformRequest( const pending = server._pendingRequests.get(cacheKey) if (pending) { return server.moduleGraph - .getModuleByUrl(removeTimestampQuery(url), options.ssr) + .getModuleByUrl(url, options.ssr) .then((module) => { if (!module || pending.timestamp > module.lastInvalidationTimestamp) { // The pending request is still valid, we can safely reuse its result From 84784ba58b8e8b4356ccce4e21a56ca55fed33f5 Mon Sep 17 00:00:00 2001 From: patak Date: Wed, 17 May 2023 14:06:54 +0200 Subject: [PATCH 4/8] chore: only pretransform JS requests --- packages/vite/src/node/server/middlewares/indexHtml.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/vite/src/node/server/middlewares/indexHtml.ts b/packages/vite/src/node/server/middlewares/indexHtml.ts index 5c128dd2b65fb6..a62cae6146201a 100644 --- a/packages/vite/src/node/server/middlewares/indexHtml.ts +++ b/packages/vite/src/node/server/middlewares/indexHtml.ts @@ -30,6 +30,7 @@ import { injectQuery, isDataUrl, isExternalUrl, + isJSRequest, joinUrlSegments, normalizePath, processSrcSetSync, @@ -85,7 +86,12 @@ function getHtmlFilename(url: string, server: ViteDevServer) { } function shouldPreTransform(url: string, config: ResolvedConfig) { - return !checkPublicFile(url, config) && !isExternalUrl(url) && !isDataUrl(url) + return ( + !checkPublicFile(url, config) && + !isExternalUrl(url) && + !isDataUrl(url) && + isJSRequest(url) + ) } const processNodeUrl = ( From 8b4ecb2373a5aa21e6204c85436421917725d16f Mon Sep 17 00:00:00 2001 From: patak Date: Wed, 17 May 2023 14:29:52 +0200 Subject: [PATCH 5/8] fix: moduleGraph after restart --- packages/vite/src/node/plugins/importAnalysis.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/vite/src/node/plugins/importAnalysis.ts b/packages/vite/src/node/plugins/importAnalysis.ts index 119f0192cabb43..21f8b807fa13c7 100644 --- a/packages/vite/src/node/plugins/importAnalysis.ts +++ b/packages/vite/src/node/plugins/importAnalysis.ts @@ -254,9 +254,9 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { // since we are already in the transform phase of the importer, it must // have been loaded so its entry is guaranteed in the module graph. const importerModule = moduleGraph.getModuleById(importer)! - if (!importerModule && depsOptimizer?.isOptimizedDepFile(importer)) { - // Ids of optimized deps could be invalidated and removed from the graph - // Return without transforming, this request is no longer valid, a full reload + if (!importerModule) { + // When the server is restarted, the module graph is cleared, so we + // return without transforming. This request is no longer valid, a full reload // is going to request this id again. Throwing an outdated error so we // properly finish the request with a 504 sent to the browser. throwOutdatedRequest(importer) From 9c56040c5357ba888774a5d98a5434eba819efbb Mon Sep 17 00:00:00 2001 From: patak Date: Wed, 17 May 2023 14:34:10 +0200 Subject: [PATCH 6/8] chore: clean up --- .../src/node/server/middlewares/indexHtml.ts | 22 ++++++------------- .../vite/src/node/server/transformRequest.ts | 4 +--- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/packages/vite/src/node/server/middlewares/indexHtml.ts b/packages/vite/src/node/server/middlewares/indexHtml.ts index a62cae6146201a..fec449781c7391 100644 --- a/packages/vite/src/node/server/middlewares/indexHtml.ts +++ b/packages/vite/src/node/server/middlewares/indexHtml.ts @@ -38,6 +38,7 @@ import { unwrapId, wrapId, } from '../../utils' +import { isCSSRequest } from '../../plugins/css' import { checkPublicFile } from '../../plugins/asset' import { getCodeWithSourcemap, injectSourcesContent } from '../sourcemap' @@ -90,7 +91,7 @@ function shouldPreTransform(url: string, config: ResolvedConfig) { !checkPublicFile(url, config) && !isExternalUrl(url) && !isDataUrl(url) && - isJSRequest(url) + (isJSRequest(url) || isCSSRequest(url)) ) } @@ -346,23 +347,14 @@ export function indexHtmlMiddleware( } } -async function preTransformRequest( - server: ViteDevServer, - url: string, - base: string, -) { +function preTransformRequest(server: ViteDevServer, url: string, base: string) { if (!server.config.server.preTransformRequests) return url = unwrapId(stripBase(url, base)) - try { - await server.moduleGraph.ensureEntryFromUrl(url) - - // transform all url as non-ssr as html includes client-side assets only - await server.transformRequest(url) - } catch (e: any) { - // it's possible that the dep fails to resolve (non-existent import) - // log the issue but avoid an unhandled exception + // transform all url as non-ssr as html includes client-side assets only + server.transformRequest(url).catch((e) => { + // Unexpected error, log the issue but avoid an unhandled exception server.config.logger.error(e.message) - } + }) } diff --git a/packages/vite/src/node/server/transformRequest.ts b/packages/vite/src/node/server/transformRequest.ts index 575b17ee0bb78e..d46df35ac65bd3 100644 --- a/packages/vite/src/node/server/transformRequest.ts +++ b/packages/vite/src/node/server/transformRequest.ts @@ -46,9 +46,7 @@ export function transformRequest( server: ViteDevServer, options: TransformOptions = {}, ): Promise { - const cacheKey = - (options.ssr ? 'ssr:' : options.html ? 'html:' : '') + - removeTimestampQuery(url) + const cacheKey = (options.ssr ? 'ssr:' : options.html ? 'html:' : '') + url // This module may get invalidated while we are processing it. For example // when a full page reload is needed after the re-processing of pre-bundled From 08f4e6fecc9f4e36a1d2a645905c34f4d8d71af2 Mon Sep 17 00:00:00 2001 From: patak Date: Wed, 17 May 2023 14:50:27 +0200 Subject: [PATCH 7/8] chore: no need for isDataUrl and isExternalUrl --- packages/vite/src/node/server/middlewares/indexHtml.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/vite/src/node/server/middlewares/indexHtml.ts b/packages/vite/src/node/server/middlewares/indexHtml.ts index fec449781c7391..a063bc91bdbaf9 100644 --- a/packages/vite/src/node/server/middlewares/indexHtml.ts +++ b/packages/vite/src/node/server/middlewares/indexHtml.ts @@ -28,8 +28,6 @@ import { ensureWatchedFile, fsPathFromId, injectQuery, - isDataUrl, - isExternalUrl, isJSRequest, joinUrlSegments, normalizePath, @@ -88,10 +86,7 @@ function getHtmlFilename(url: string, server: ViteDevServer) { function shouldPreTransform(url: string, config: ResolvedConfig) { return ( - !checkPublicFile(url, config) && - !isExternalUrl(url) && - !isDataUrl(url) && - (isJSRequest(url) || isCSSRequest(url)) + !checkPublicFile(url, config) && (isJSRequest(url) || isCSSRequest(url)) ) } From b3087298454945ce269cdde49569548da0b47e65 Mon Sep 17 00:00:00 2001 From: patak Date: Wed, 17 May 2023 14:52:17 +0200 Subject: [PATCH 8/8] chore: clean up --- packages/vite/src/node/server/transformRequest.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vite/src/node/server/transformRequest.ts b/packages/vite/src/node/server/transformRequest.ts index d46df35ac65bd3..b08a01e5d01b9e 100644 --- a/packages/vite/src/node/server/transformRequest.ts +++ b/packages/vite/src/node/server/transformRequest.ts @@ -73,7 +73,7 @@ export function transformRequest( const pending = server._pendingRequests.get(cacheKey) if (pending) { return server.moduleGraph - .getModuleByUrl(url, options.ssr) + .getModuleByUrl(removeTimestampQuery(url), options.ssr) .then((module) => { if (!module || pending.timestamp > module.lastInvalidationTimestamp) { // The pending request is still valid, we can safely reuse its result