I have a simple error printing library which successfully retrieves the source-mapped file paths in Node.js and gets the TypeScript file paths/locations, for example. For that, basically it's this code and the @cspotcode/source-map library (that is a synchronous version of the async mozilla library, which is necessary for capturing the sync stack trace and printing on error):
import smc from '@cspotcode/source-map'
import fs from 'fs'
import pathResolve from 'path'
const SOURCE_MAP_CACHE: Record<string, smc.SourceMapConsumer> = {}
function loadSourcePath(line: string): smc.SourceMapConsumer | void {
const link = SOURCE_MAP_CACHE[`${line}`]
if (link) {
return link
}
const fileLink = line.replace(/^file:\/\//, '')
if (fs.existsSync(`${fileLink}.map`)) {
const mapContent = fs.readFileSync(`${fileLink}.map`, 'utf-8')
const json = JSON.parse(mapContent) as smc.RawSourceMap
const sm = new smc.SourceMapConsumer(json)
SOURCE_MAP_CACHE[`${line}`] = sm
return sm
}
}
function readPath(path: string, context: string): string {
const relative = pathResolve.relative(
process.cwd(),
pathResolve.resolve(context, path),
)
return relative.startsWith('.') ? relative : `./${relative}`
}
function readHostLinkFile(
file: string,
line: number,
rise: number,
): [string, number | undefined, number | undefined] {
const link = loadSourcePath(file)
const trace = {
column: rise,
filename: file,
line: line,
}
if (link) {
const token = link.originalPositionFor(trace)
if (token.source) {
return [
readPath(
token.source,
pathResolve.dirname(file.replace(/^file:\/\//, '')),
),
token.line == null ? undefined : token.line,
token.column == null ? undefined : token.column,
]
} else {
return [file, line, rise]
}
} else {
return [file, line, rise]
}
}
How can I do this same thing in the browser? My errors currently link to the compiled JS output, like this, even though there is the //# sourceMappingURL at the bottom of the file.
What do I need to do to map .js paths with line:column numbers (such as from an error stack trace) to go to the TypeScript file through source maps, in the browser? Do I like need to:
- Fetch the
.jsfile withawait fetch(url). - And parse the
//# sourceMappingURLdata-uri somehow?
Or is there a different way? Or any libraries for this? Looked around a bit but found almost nothing. That sourcemap library for node.js depends on the fs, so probably won't work there.
