From 0dc9310a46898558760c53492f5d686aebfc438d Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Wed, 7 Apr 2021 19:19:54 -0400 Subject: [PATCH] fix(injectSourcesContent): warn once per sourcemap for missing sources https://github.com/vitejs/vite/pull/2904 --- packages/vite/src/node/server/sourcemap.ts | 73 ++++++++++++++----- .../vite/src/node/server/transformRequest.ts | 2 +- 2 files changed, 56 insertions(+), 19 deletions(-) diff --git a/packages/vite/src/node/server/sourcemap.ts b/packages/vite/src/node/server/sourcemap.ts index 42fb94e5bdb2df..c024a3aeaed61f 100644 --- a/packages/vite/src/node/server/sourcemap.ts +++ b/packages/vite/src/node/server/sourcemap.ts @@ -1,29 +1,66 @@ -import { promises as fs } from 'fs' import path from 'path' +import { promises as fs } from 'fs' +import { Logger } from '../logger' +import { createDebugger } from '../utils' import { ModuleGraph } from './moduleGraph' +const isDebug = !!process.env.DEBUG +const debug = createDebugger('vite:sourcemap', { + onlyWhenFocused: true +}) + +interface SourceMapLike { + sources: string[] + sourcesContent?: (string | null)[] + sourceRoot?: string +} + export async function injectSourcesContent( - map: { sources: string[]; sourcesContent?: string[]; sourceRoot?: string }, + map: SourceMapLike, file: string, + logger: Logger, moduleGraph?: ModuleGraph ): Promise { - const sourceRoot = await fs.realpath( - path.resolve(path.dirname(file), map.sourceRoot || '') - ) - const needsContent = !map.sourcesContent - if (needsContent) { - map.sourcesContent = [] - } - await Promise.all( - map.sources.filter(Boolean).map(async (sourcePath, i) => { - const mod = await moduleGraph?.getModuleByUrl(sourcePath) - sourcePath = mod?.file || path.resolve(sourceRoot, decodeURI(sourcePath)) - if (moduleGraph) { - map.sources[i] = sourcePath - } - if (needsContent) { - map.sourcesContent![i] = await fs.readFile(sourcePath, 'utf-8') + let sourceRoot: string | undefined + try { + // The source root is undefined for virtual modules and permission errors. + sourceRoot = await fs.realpath( + path.resolve(path.dirname(file), map.sourceRoot || '') + ) + } catch {} + + const { sourcesContent } = map + const missingSources: string[] = [] + map.sourcesContent = await Promise.all( + map.sources.map((sourcePath, i) => { + if (sourcePath) { + sourcePath = decodeURI(sourcePath) + const mod = await moduleGraph?.getModuleByUrl(sourcePath) + if (mod.file) { + sourcePath = mod.file + map.sources[i] = sourceRoot + ? path.relative(sourceRoot, sourcePath) + : sourcePath + } else if (sourceRoot) { + sourcePath = path.resolve(sourceRoot, sourcePath) + } + if (sourcesContent) { + return sourcesContent[i] + } + return fs.readFile(sourcePath, 'utf-8').catch(() => { + missingSources.push(sourcePath) + return null + }) } + return null }) ) + + // Use this command… + // DEBUG="vite:sourcemap" vite build + // …to log the missing sources. + if (missingSources.length) { + logger.warnOnce(`Sourcemap for "${file}" points to missing source files`) + isDebug && debug(`Missing sources:\n ` + missingSources.join(`\n `)) + } } diff --git a/packages/vite/src/node/server/transformRequest.ts b/packages/vite/src/node/server/transformRequest.ts index 5b2d66d7961507..a195bbfb37fae7 100644 --- a/packages/vite/src/node/server/transformRequest.ts +++ b/packages/vite/src/node/server/transformRequest.ts @@ -144,7 +144,7 @@ export async function transformRequest( if (map && mod.file) { map = (typeof map === 'string' ? JSON.parse(map) : map) as SourceMap if (map.mappings && !map.sourcesContent) { - await injectSourcesContent(map, mod.file) + await injectSourcesContent(map, mod.file, logger) } }