From de60f1e3d1eb03167362cf8ce0c6c4071430f812 Mon Sep 17 00:00:00 2001 From: Bjorn Lu Date: Sun, 17 Mar 2024 23:25:48 +0800 Subject: [PATCH] perf(transformRequest): fast-path watch and sourcemap handling (#16170) --- packages/vite/src/node/server/sourcemap.ts | 32 +++++++++++++++- .../vite/src/node/server/transformRequest.ts | 37 +++++++------------ 2 files changed, 45 insertions(+), 24 deletions(-) diff --git a/packages/vite/src/node/server/sourcemap.ts b/packages/vite/src/node/server/sourcemap.ts index eafde8c25b67d1..a0ed31968b6c41 100644 --- a/packages/vite/src/node/server/sourcemap.ts +++ b/packages/vite/src/node/server/sourcemap.ts @@ -1,8 +1,9 @@ import path from 'node:path' import fsp from 'node:fs/promises' +import convertSourceMap from 'convert-source-map' import type { ExistingRawSourceMap, SourceMap } from 'rollup' import type { Logger } from '../logger' -import { createDebugger } from '../utils' +import { blankReplacer, createDebugger } from '../utils' const debug = createDebugger('vite:sourcemap', { onlyWhenFocused: true, @@ -143,3 +144,32 @@ export function applySourcemapIgnoreList( if (!map.x_google_ignoreList) map.x_google_ignoreList = x_google_ignoreList } } + +export async function extractSourcemapFromFile( + code: string, + filePath: string, +): Promise<{ code: string; map: SourceMap } | undefined> { + const map = ( + convertSourceMap.fromSource(code) || + (await convertSourceMap.fromMapFileSource( + code, + createConvertSourceMapReadMap(filePath), + )) + )?.toObject() + + if (map) { + return { + code: code.replace(convertSourceMap.mapFileCommentRegex, blankReplacer), + map, + } + } +} + +function createConvertSourceMapReadMap(originalFileName: string) { + return (filename: string) => { + return fsp.readFile( + path.resolve(path.dirname(originalFileName), filename), + 'utf-8', + ) + } +} diff --git a/packages/vite/src/node/server/transformRequest.ts b/packages/vite/src/node/server/transformRequest.ts index 8341f14a70a737..5dc6e3921215af 100644 --- a/packages/vite/src/node/server/transformRequest.ts +++ b/packages/vite/src/node/server/transformRequest.ts @@ -2,14 +2,12 @@ import fsp from 'node:fs/promises' import path from 'node:path' import { performance } from 'node:perf_hooks' import getEtag from 'etag' -import convertSourceMap from 'convert-source-map' import MagicString from 'magic-string' import { init, parse as parseImports } from 'es-module-lexer' import type { PartialResolvedId, SourceDescription, SourceMap } from 'rollup' import colors from 'picocolors' import type { ModuleNode, ViteDevServer } from '..' import { - blankReplacer, createDebugger, ensureWatchedFile, injectQuery, @@ -24,7 +22,11 @@ import { checkPublicFile } from '../publicDir' import { isDepsOptimizerEnabled } from '../config' import { getDepsOptimizer, initDevSsrDepsOptimizer } from '../optimizer' import { cleanUrl, unwrapId } from '../../shared/utils' -import { applySourcemapIgnoreList, injectSourcesContent } from './sourcemap' +import { + applySourcemapIgnoreList, + extractSourcemapFromFile, + injectSourcesContent, +} from './sourcemap' import { isFileServingAllowed } from './middlewares/static' import { throwClosedServerError } from './pluginContainer' @@ -263,21 +265,19 @@ async function loadAndTransform( throw e } } - ensureWatchedFile(server.watcher, file, config.root) + if (code != null) { + ensureWatchedFile(server.watcher, file, config.root) + } } if (code) { try { - map = ( - convertSourceMap.fromSource(code) || - (await convertSourceMap.fromMapFileSource( - code, - createConvertSourceMapReadMap(file), - )) - )?.toObject() - - code = code.replace(convertSourceMap.mapFileCommentRegex, blankReplacer) + const extracted = await extractSourcemapFromFile(code, file) + if (extracted) { + code = extracted.code + map = extracted.map + } } catch (e) { - logger.warn(`Failed to load source map for ${url}.`, { + logger.warn(`Failed to load source map for ${file}.\n${e}`, { timestamp: true, }) } @@ -406,15 +406,6 @@ async function loadAndTransform( return result } -function createConvertSourceMapReadMap(originalFileName: string) { - return (filename: string) => { - return fsp.readFile( - path.resolve(path.dirname(originalFileName), filename), - 'utf-8', - ) - } -} - /** * When a module is soft-invalidated, we can preserve its previous `transformResult` and * return similar code to before: