當前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
JavaScript打印所有被执行函数堆栈
生活随笔
收集整理的這篇文章主要介紹了
JavaScript打印所有被执行函数堆栈
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
需求
項目地址
Github
效果
思路
實現
const fs = require('fs') const escodegen = require("escodegen"); const esprima = require('esprima');const srcPath = "./demo/three.js"; const destPath = './demo/three_log.js'; /** 是否顯示堆棧信息 */ const isShowStack = false; let prevHandleTime = 0;main(srcPath, destPath);function main(srcPath, destPath) {log('讀取文件');const program = fs.readFileSync(srcPath, "utf-8");log('文本轉AST');let tree = esprima.parseScript(program);log('處理AST');handleTree(tree);log('AST轉文本');const result = escodegen.generate(tree);// console.log(result);log('寫入新文本');fs.writeFileSync(destPath, result);log('Finish'); }function handleTree(tree, methodName = "") {if (!tree) return;if (checkIsObject(tree)) {switch (tree.type) {case 'BlockStatement':if (tree.body && checkIsArray(tree.body)) {let logStr = '';if (isShowStack) {logStr =`console.groupCollapsed("---------------------------------${methodName}"); console.trace("${methodName}");console.groupEnd(); `;} else {logStr = `console.log("---------------------------------${methodName}");`;}const consoleBody = esprima.parseScript(logStr).body;if (tree.body.length > 0) {// 空方法不添加log for (let i = consoleBody.length - 1; i >= 0; i--)tree.body.unshift(consoleBody[i]);}handleTree(tree.body, methodName);return;}break;case 'AssignmentExpression':tree.right && handleTree(tree.right, getName(methodName, tree.left));break;case 'CallExpression':if (tree.callee) {handleTree(tree.callee, methodName);}if (tree.arguments) {handleTree(tree.arguments, methodName);}break;case 'ClassDeclaration':tree.body && handleTree(tree.body, getName(methodName, tree));break;default:tree.body && handleTree(tree.body, methodName);break;}return;}if (checkIsArray(tree)) {for (let i = 0; i < tree.length; i++) {let item = tree[i];switch (item.type) {case 'MethodDefinition':if (item.kind === 'get' || item.kind === 'set') {// 過濾 get/set 方法} else {item.value && handleTree(item.value, getName(methodName, item));}break;case 'ExpressionStatement':item.expression && handleTree(item.expression, methodName);break;case 'ClassDeclaration':item.body && handleTree(item.body, getName(methodName, item));break;case 'ForStatement':case 'ForInStatement':// for 語句不添加break;case 'FunctionDeclaration':// 方法聲明item.body && handleTree(item.body, getName(methodName, item));break;default:item.body && handleTree(item.body, methodName);break;}}return;}console.error('什么鬼'); }function getName(methodName, item) {let itemName = '';if (item) {if (item.id)itemName = item.id.name;else if (item.key)itemName = item.key.name;else if (item.property)itemName = item.property.name;}let dot = '';if (methodName && itemName)dot = '.';return methodName + dot + itemName; }function checkIsArray(arr) {return Object.prototype.toString.call(arr) === '[object Array]'; }function checkIsObject(obj) {return Object.prototype.toString.call(obj) === '[object Object]'; }function getTime() {const now = Date.now();let result = 0;if (prevHandleTime !== 0) {result = now - prevHandleTime;}prevHandleTime = now;return ' ' + result + ' ms'; }function log(str) {console.log(str, getTime()); }拓展
靈活使用, 可大幅提高分析效率, 如:
總結
以上是生活随笔為你收集整理的JavaScript打印所有被执行函数堆栈的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: M05-MongoDB数据库核心知识
- 下一篇: 使用FVD时遇到的问题记录:使用tens