-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Apply source maps to profiles #50894
Comments
There has been no activity on this feature request for 5 months. To help maintain relevant open issues, please add the
never-stale
|
maintainers: can we get some sort of signal here so that this issue doesn't stay open unnecessarily? |
@mbrevda, I'm having similar a issue did you find any workarounds or post augmentation tools for this? |
Here's a script I'm using to augment post profileimport {readFile} from 'fs/promises';
import {SourceMapConsumer} from 'source-map';
import {join} from 'path';
const sourceMap = {};
const loadSourceMap = async (codePath, filepath) => {
const sourceFile = await readFile(codePath + '/' + filepath, 'utf-8');
const mapFileUrlLine = sourceFile
.split('\n')
.reverse()
.find((line) => line.startsWith('//# sourceMappingURL='));
if (!mapFileUrlLine) {
console.warning('could not find sourceMappingURL line for', filepath);
return false;
}
const mapFileUrl = mapFileUrlLine.replace('//# sourceMappingURL=', '');
const mapFile = await readFile(codePath + '/' + mapFileUrl, 'utf-8');
if (!mapFile) {
console.warning(`could not find source map file ${mapFile} for`, filepath);
return false;
}
return await new SourceMapConsumer(mapFile);
};
const remapProfile = async (projectDir, trace) => {
const codePath = projectDir + '/dist';
const mappedNodes = [];
for (const [index, node] of trace.nodes.entries()) {
mappedNodes.push(node);
const {url, lineNumber, columnNumber, functionName} = node.callFrame;
if (!url || !lineNumber) continue;
const {protocol, pathname} = new URL(url);
if (!pathname.startsWith(codePath)) continue;
const filepath = pathname.replace(codePath + '/', '');
if (sourceMap[filepath] === false) continue; // we already tried to load this source map and failed
if (!(filepath in sourceMap)) {
sourceMap[filepath] = await loadSourceMap(codePath, filepath);
}
if (!sourceMap[filepath]) continue;
const {source, line, column, name} = sourceMap[
filepath
].originalPositionFor({
line: lineNumber,
column: columnNumber,
});
if (!source && !line && !column && !name) continue;
const mappedUrl = source ? `${protocol}//` + join(codePath, source) : url;
// use original function name if available
let mappedFunctionName = functionName;
if (name) {
// if we have a name, but no function name, use the name
if (!functionName) {
mappedFunctionName = name;
} else {
// if we have both, use both
mappedFunctionName = `${name} (${functionName})`;
}
}
mappedNodes[index] = {
...mappedNodes[index],
callFrame: {
...(mappedNodes[index]?.callFrame || {}),
url: mappedUrl,
lineNumber: line,
columnNumber: column,
functionName: mappedFunctionName,
},
};
}
return {...trace, nodes: mappedNodes};
};
export default async (projectDir, profile) => {
return await remapProfile(projectDir, profile);
};
</details> |
What is the problem this feature will solve?
When debugging bundled/compiled/minified code, it's difficult to read a profile as locations and many function names point to the compiled code.
What is the feature you are proposing to solve the problem?
Apply source maps to profiles (perhaps when
--enable-source-maps
is passed).What alternatives have you considered?
post-augmentation (via the source-map package), or other tools (such as speedscope) which claim to be able to apply sourcemaps (but dont always work).
The text was updated successfully, but these errors were encountered: