diff --git a/packages/vite/src/node/server/sourcemap.ts b/packages/vite/src/node/server/sourcemap.ts index 5e11f8491443e4..515b5a605a3157 100644 --- a/packages/vite/src/node/server/sourcemap.ts +++ b/packages/vite/src/node/server/sourcemap.ts @@ -1,20 +1,54 @@ -import { promises as fs } from 'fs' import path from 'path' +import { promises as fs } from 'fs' +import { Logger } from '../logger' +import { createDebugger } from '../utils' + +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 }, - file: string + map: SourceMapLike, + file: string, + logger: Logger ): Promise { - const sourceRoot = await fs.realpath( - path.resolve(path.dirname(file), map.sourceRoot || '') - ) - map.sourcesContent = [] - await Promise.all( - map.sources.filter(Boolean).map(async (sourcePath, i) => { - map.sourcesContent![i] = await fs.readFile( - path.resolve(sourceRoot, decodeURI(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 missingSources: string[] = [] + map.sourcesContent = await Promise.all( + map.sources.map((sourcePath) => { + if (sourcePath) { + sourcePath = decodeURI(sourcePath) + if (sourceRoot) { + sourcePath = path.resolve(sourceRoot, sourcePath) + } + 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 ebb29dc461ea72..483df46d06e6e5 100644 --- a/packages/vite/src/node/server/transformRequest.ts +++ b/packages/vite/src/node/server/transformRequest.ts @@ -147,7 +147,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) } }