找到死的JavaScript代码?

时间:2010-11-09 17:41:14

标签: javascript refactoring dead-code

我们正在重构遗留的网络应用程序,因此“杀死”了相当多的JavaScript代码,但我们害怕因为不确定而删除我们认为的死代码。是否有任何工具/技术可以在JavaScript中正确识别死代码?

9 个答案:

答案 0 :(得分:10)

grep 。用它来查找函数调用。假设您有一个名为dostuff()的方法。在项目的根目录中使用grep -r "dostuff()" * --color。除非您找到除定义之外的任何内容,否则您可以安全地删除它。

ack也是 grep 的明显替代品。

答案 1 :(得分:9)

没有寻找太复杂的东西:

答案 2 :(得分:8)

如果你的代码使用“eval”,那么很难找到一个代码没有通过一些模糊的方法组装字符串并且评估它的人,调用你的死代码。 (真正讨厌的东西可能会在包含eval的字符串上调用eval ...)。

您还必须担心来自外部代码的来电;许多网页使用HTML“on”属性来调用JavaScript代码。

所以你需要做的是找到看似已死的方法/声明,找到并审查所有的eval调用,找到并审查所有“on”属性。

使用其他人建议的测试覆盖率是一种获取可能死代码的初始列表的方法。您显然希望尽可能多地运用功能来消除可能死亡的候选者,然后搜索剩余的候选者以查看代码中是否有调用。查找evals和on-events是一个搜索代码的事情。

Grep可能会起作用,虽然逐个浏览你的名字列表可能很痛苦,输入正确的搜索,从输出中猜出哪些不是误报,然后在编辑器中检查它们之一。

您可以查看我们的SD Source Code Search Engine (SCSE),它可以针对许多语言进行语言特定的搜索,包括各种类型的HTML页面和JavaScript。您可以轻松地限制SCSE仅检查JavaScript代码中的函数调用(例如,忽略注释和字符串)以查找剩余的候选者和/或eval,并仅检查HTML页面中的“on *”属性(例如,忽略HTML页面中的所有其他文本)。它使用GUI来接受搜索查询,显示命中,并提取包含命中的源文本以便于检查。如果需要的话,它甚至会把你带到你的编辑器上。

对于静态分析解决方案,您需要能够解析代码并确定哪些名称引用哪些实体的工具;范围问题。然后,您需要能够通过代码确定合理的执行路径,模拟动态对象结构和那些讨厌的逃避。为此你需要一个相当复杂的引擎,并且可能需要一些工程,除非有人发生这种情况,我怀疑这一点。

我们的DMS Software Reengineering Toolkit就是这样一个引擎,它有一个完整的JavaScript(和HTML)解析器。虽然我们没有使用DMS来实现JavaScript,但我们已经使用DMS为Java构建了这样一个死代码移除器。你给它提供了Java代码,它产生了一个“看似已死”的类,方法和字段列表(包括死的传递闭包:如果类A死了,引用B,A的引用不计算作为B)的实际引用,代码的修改版本,删除了所有“死”的东西。您决定是否相信该报告;如果你这样做,你保留代码。如果不这样做,则修改代码以确保该死的东西没有死,然后重新运行。

答案 3 :(得分:7)

JetBrains的WebStorm IDE可以突出显示项目中的死代码和未使用的变量。

答案 4 :(得分:6)

您可以将代码优化程序用作Google Closure Compiler,但它通常用于最小化代码。

function hello(name) {
alert('Hello, ' + name);
}

function test(){
alert('hi');
}

hello('New user');

将导致

alert("Hello, New user");

例如。

您可以做的另一件事是使用Chrome的开发人员工具(或Firebug)来查看所有函数调用。在配置文件下,您可以看到哪些功能随时间被调用,哪些功能不被调用。

DT Profiles

答案 5 :(得分:3)

Chrome推出了一项新功能,可让开发人员看到代码覆盖率,即执行了哪些代码行。

这当然不是一站式解决方案,但可以向开发人员伸出援助之手以获得代码洞察力。

查看此link了解详情

作为 Chrome 59 版本

的一部分展开

tools

答案 6 :(得分:2)

如果你想自动执行此操作,我会看一下https://github.com/joelgriffith/navalia,它会公开一个自动API来执行此操作:

const { Chrome } = require('navalia');
const chrome = new Chrome();

chrome.goto('http://joelgriffith.net/', { coverage: true })
  .then(() => chrome.coverage('http://joelgriffith.net/main.bundle.js'))
  .then((stats) => console.log(stats)) // Prints { total: 45913, unused: 5572, 
  percentUnused: 0.12135996340905626 }
  .then(() => chrome.done());

更多信息:https://joelgriffith.github.io/navalia/Chrome/coverage/

答案 7 :(得分:1)

您可以使用deadfile库: https://m-izadmehr.github.io/deadfile/

它可以在任何JS项目中简单地找到未使用的文件。

没有任何配置,它支持ES6,JSX和Vue文件: enter image description here

答案 8 :(得分:0)

我讨厌这个问题,尽管解析很繁重的javascript生态系统,但没有解决这个问题的好工具。如另一个答案中所述,deadfile非常简洁,但是我无法使其适用于我的代码库,该代码库使用来自src目录的绝对导入。以下bash足以使您了解是否没有将文件导入任何地方(我发现了一些!),这很容易手动验证。

for f in $(find src -name '*.js' | grep -E 'src/(app|modules|components).*\.js$' | grep -v '.test.js'); do
  f=${f/src\//};
  f=${f/\/index.js/};
  f=${f/.js/};

  echo "$f imported in"$(grep -rl "$f" src | wc -l)" files"
done

我不在乎测试/资源,因此app | modules | components位。字符串替换也可以进行大量清理,但希望这对某人有用。