javascript 保留行号的控制台代理,具有前缀AND,支持字符串替换

6jygbczu  于 2023-02-15  发布在  Java
关注(0)|答案(1)|浏览(99)

我已经创建了一个console代理,它现在只不过是在写入控制台的每一行上添加一个前缀,它工作得很好,甚至保持行号完整(也就是说,消息具有浏览器显示的正确来源)。

const disabledMethodsInProduction = ['debug', 'log', 'trace'];
logger = new Proxy(console, {
    get (target, method) {
        if (method in target) {
            if (!developmentMode && disabledMethodsInProduction.includes(method)) {
                return () => { /* NOP */ };
            }
            // 'loggingID' is a string, defined elsewhere.
            return target[method].bind(console, `${loggingID}:`);
        }
        throw new Error(`Method '${method}()' not implemented in console.`);
    }
});

上述代码的问题与我研究过的其他解决方案相同(并注解)在堆栈溢出中。也就是说,前缀(在本例中为loggingID字符串)现在是console对象方法的FIRST参数,因此当使用包含字符串替换的消息调用上述代理对象时(例如%c),则不会处理它们,因为它们现在是SECOND参数。
修复很简单:代替返回console方法,可以返回捕获所提供的参数的新函数,并且如果第一个是字符串并且包含字符串替换,则前缀被插入到 * that * 参数中,而不是作为不同的参数:

return function () {
    // Do things with 'arguments' and pass it to the proper console method.
    const args = Array.from(arguments);
    // Yes, I know, first I should check args[0] to see
    // if it is a string and contains string substitutions.
    args[0] = `${loggingID}: ` + args[0];
    target[method](...args);  // THIS line number will appear in console messages, obviously.
}

不幸的是,这样做显然会破坏原来的行号。
有什么解决方案可以同时具有两个特性,也就是说,同时保留行号和捕获参数?
我可以忍受失去使用字符串替换的能力,因为保留行号对我来说更重要,但我只是好奇如何解决这个问题,我希望同时拥有这两个特性。

bogh5gae

bogh5gae1#

我找到了一种方法来实现我所需要的,但需要一组额外的括号:

const disabledMethodsInProduction = ['debug', 'log', 'trace'];
logger = new Proxy(console, {
    get (target, method) {
        if (method in target) {
            if (!developmentMode && disabledMethodsInProduction.includes(method)) {
                return () => { /* NOP */ };
            }
            return function (...args) {
                // An additional check for string subtitution chars is needed.
                if (typeof args[0] === 'string') {
                    // 'loggingID' is a string, defined elsewhere.
                    args[0] = `${loggingID}: ${args[0]}`;
                }
                return target[method].bind(console, ...args);
            };
        }
        throw new Error(`Method '${method}()' not implemented in console.`);
    }
});

// Should be used like this:
// logger.log('%cThis is bold', 'font-weight:bold')();

注意调用代理对象方法时多出的一对括号。
该解决方案:
1.保留行号,显示调用方的行号。
1.可以在生产中有选择地禁用。
1.允许第一个参数中的字符串替换。
如果有人知道如何去掉那对难看的括号,我洗耳恭听。

相关问题