在当前有很多依赖项的项目中,我需要一种对特定库禁用控制台访问的方法,以使这些文件不能使用任何控制台功能。
我当然可以通过简单地在库捆绑中找到并替换控制台功能来禁用控制台功能,但是由于该项目具有很多依赖关系,因此更新库变得非常麻烦。
我知道我可以通过使用空功能块覆盖控制台功能来禁用控制台功能:
console.log = function(){};
但是,这将禁用整个项目的控制台功能。因此,我正在寻找一种实现方式,或者寻找一行代码来禁用特定文件或代码块的控制台功能。
答案 0 :(得分:2)
console.log
写一个白名单“中间件”
// Preserve the old console.log
const log = console.log;
// Used a dictionary because it's faster than lists for lookups
const whiteListedFunctions = {"hello": true};
// Whitelisting "middleware". We used the function's name "funcName"
// as a criteria, but it's adaptable
const isWhitelisted = callerData => callerData.funcName in whiteListedFunctions;
// Replacing the default "console.log"
console.log = arg => {
const stack = new Error().stack.split("at")[2].trim().split(' ');
const fileParts = stack[1].substr(1, stack[1].length - 2).split(':');
const callerData = {
funcName: stack[0],
file: fileParts.slice(0, fileParts.length - 2).join(':'),
lineColNumber: fileParts.slice(fileParts.length - 2).join(':')
};
if (isWhitelisted(callerData)) { // Filtering happens here
log(arg);
}
};
// Define the calling functions
function hello() { console.log("hello"); }
function world() { console.log("world"); }
hello(); // => Prints hello
world(); // => Doesn't print anything
console.log
的函数的名称,或者可能包含文件名,甚至可能包含行号和列号 >。console.log
。该记录器将要记录的消息作为参数(也许有多个参数?)。在此功能中,您还需要找到与呼叫者功能(想要调用console.log
)有关的数据。这部分有点“棘手”(但是在这种情况下,它完成了工作)。我们基本上会创建一个 Error
并检查其stack
属性,例如new Error().stack
。这将给我们这种痕迹
错误 在console.log.arg [作为日志](https://stacksnippets.net/js:25:7) 打招呼(https://stacksnippets.net/js:41:11) 在https://stacksnippets.net/js:48:1
在处理(分割,映射等)跟踪之后,我们获得了调用者函数数据。例如,这里有
此位是受VLAZ's中How to disable console.log messages based on criteria from specific javascript source (method, file) or message contents答案的启发,因此请务必将其签出。真的很好,内容很详尽。
要了解跟踪,我们可以执行new Error().stack.split("at")[INDEX].trim().split(' ')
,其中INDEX
是要在堆栈跟踪中定位的函数调用的位置。因此,如果您要获得与本示例中使用的不同的“级别” ,请尝试更改INDEX
答案 1 :(得分:0)
只需重新定义控制台以登录条件,您的条件当然就是检查哪个库正在访问该功能:
// Your condition, could be anything
let condition = true;
/* Redefine the console object changing only the log function with your new version and keeping all the other functionalities intact
*/
let console = (old => ({
...old,
log: text => { if (condition) old.log(text) }
}))(window.console)
// Redefine the old console
window.console = console;
console.log('hello!')
希望对您有所帮助:)
答案 2 :(得分:0)
是的,您可以根据文件的路径禁用控制台日志!这是一个解决方案:
// in ./loud-lib.js module.exports = { logsSomething: () => console.log('hello from loud-lib') }
// in ./silent-lib.js module.exports = { logsSomething: () => console.log('hello from silent-lib') }
// in ./index.js const loud = require('./loud-lib'); const silent = require('./silent-lib'); // save console.log const log = console.log; // redefinition of console.log console.log = (...params) => { // define regexp for path of libraries that log too much const loudLibs = [/loud-lib/]; // check if the paths logged in the stacktract match with at least one regexp const tooLoud = !!loudLibs.find(reg => reg.test(new Error().stack)); // log only if the log is coming from a library that doesn't logs too much if (!tooLoud) log(...params); }; loud.logsSomething(); silent.logsSomething();
$ node ./index.js hello from silent-lib
这是基于以下事实:new Error()
会生成堆栈跟踪,该堆栈跟踪可识别(递归地)错误来自哪个文件。
基于此观察,您可以定义一个正则表达式数组,该数组与您不希望听到其日志的库的名称匹配。通过重新定义console.log
,您可以变得非常具体和富有创意,但是我保持了简单。
但是,请注意这一点(尤其是在使用Webpack时):如果将所有JS资产捆绑到一个bundle.js
中,则堆栈跟踪将始终指向bundle.js
,从而记录所有内容。您必须走出我的代码的距离,例如使用stack-source-map,但是我在您的项目上没有足够的细节来提供解决方案。我希望以上想法对您足够。