javascript - 如何通过 console.log 使用自定义 URL 打开浏览器调试器
我有一个脚本用于添加和/或修改日志到控制台的数据,我们称它为 logger.js,可以像 logger.warn(data) 这样调用它。
在控制台查看的所有日志都会打印它们的来源,如 logger.js:123:45,而不是实际的来源。为了解决这个问题,我正在解析跟踪以找到实际的来源,并将其也记录到控制台中。点击时会打开正确的文件/位置,但在一个单独的浏览器标签页中。
是否可以在控制台调试工具中打开这个 URL?如果可以,该如何操作?
答案#1
使用 强制 源映射
我最近遇到了类似的需求,并意识到我可以为此使用源映射。这一想法受到了这个看似无关的问题的很大启发。
所以,我们想要一个可点击的链接,能够
- 指向我们的文件
- 并指出正确的行号
而且我们知道该文件的 URL 和行号。我们也知道要抛出什么错误。
为了到那里,我们
- 创建一个包含单个
throw语句的虚拟文件 - 附加一个真正指向我们文件的源映射
- 对生成的代码使用
eval - 在浏览器控制台中惊叹于结果
<script type="module">
import {encode} from 'https://cdn.jsdelivr.net/npm/[email /+esm'
throwClickableError(new Error("Here is the error that points at a Markdown file. Isn't this magic?"), {
url: "https://cdn.jsdelivr.net/npm/[email /LICENSE.md",
text: null,
line: 16,
column: 3,
});
/**
* @typedef ErrorLocation
* @prop {string} url URL to point at
* @prop {string | null} text Source code to point at
* @prop {number} line Line number to point at (1-based)
* @prop {number} column Column to point at (1-based)
*/
/**
*
* @param {Error} error
* @param {ErrorLocation} source
*/
export function throwClickableError(error, source) {
// We remap an error directly to where we need it to be
// The fields are
// 1. Generated column (aka 0)
// 2. Index into sources list (aka 0)
// 3. Original line number (zero based)
// 4. Original column number (zero based)
// Limitations:
// - In Firefox, errors will point at the line where they happened.
// - In Chrome, errors will start at the correct column, but will go until the end of the line
let mappings = encode([
0,
0,
Math.max(0, source.line - 1),
Math.max(0, source.column - 1),
]);
const sourceMap = {
version: 3,
file: null,
sources: [source.url],
sourcesContent: [source.text],
names: [],
mappings,
};
const encodedSourceMap = btoa(
unescape(encodeURIComponent(JSON.stringify(sourceMap))),
);
// Only display the error message once
let message = error.message;
error.message = undefined;
let generatedCode = `(err, message) => { throw new Error(message, {cause:err}); }
//# sourceMappingURL=data:application/json;base64,${encodedSourceMap}
//# sourceURL=${source.url}`;
// Shrink the stack trace on Chrome
let oldLimit = 0;
if ("stackTraceLimit" in Error) {
oldLimit = Error.stackTraceLimit;
Error.stackTraceLimit = 1;
}
// Run the generated code
try {
(0, eval)(generatedCode)(error, message);
} finally {
if ("stackTraceLimit" in Error) {
Error.stackTraceLimit = oldLimit;
}
}
}
</script>
<h1>Open the browser console</h1>
And then click on it.
Isn't this cool?在 Chrome 上的结果看起来像这样
Uncaught Error: Here is the error that ... LICENSE.md:3
at eval (LICENSE.md:16:3)
Caused by: Error
at js:12:21
