有没有一种工具可以删除JavaScript中未使用的方法?

50

我收到了一些第三方的JavaScript文件集合,想要删除所有未使用的方法以使文件大小更加合理。

有没有人知道一个可以对JavaScript进行这样操作的工具?至少可以提供已使用或未使用方法的列表,这样我可以手动进行删减。这将是在运行像YUI JavaScript压缩器这样的工具之外的额外步骤...

否则,我的想法是编写一个Perl脚本来帮助我完成这个任务。

7个回答

44

不行。因为你可以像这样以非常动态的方式“使用”方法。

obj[prompt("Gimme a method name.")]();

1
是的,你能做的最好只是粗略地通过。 - Nosredna
42
我将在所有的项目中开始使用这种方法。 - TJ L
6
除了示例和其他用户生成/随机生成的方法外,你不能简化这些文件吗? - jedierikb
8
这篇答案在对于讨论有多难提出了很好的观点,但是这个答案是100%错误的。对于那些认为没有办法确定运行哪些函数的人,你需要动动你的想象力。追踪技术已经存在很长时间了,并且完全可行。仅因为某种语言尚未拥有此功能并不意味着它是不可能的或将来不会提供。这篇答案较短,缺乏很多潜在有用的信息。 - SgtPooki
“不,这是徒劳无功的”是没有价值的答案——字面上。这不是一个独特的问题,已经有大量人力投入其中——可以查看@foson的回答作为正确方向的一步。 - Kevin Nielsen
显示剩余5条评论

19

看看 JSCoverage 。生成代码覆盖率统计数据,显示程序中哪些行已执行(哪些未执行)。


1
注意:JSCoverage 代码库的任何未来开发可能会在 GitHub 上新的 JSCover(http://tntim96.github.io/JSCover/)项目中进行,该项目重用了大量 JSCoverage 代码,并旨在与 JSCoverage 具有高度向后兼容性。 JSCoverage 本身不太可能有任何进一步的发布。 - Luckylooke

7
我希望能够删除所有未使用的方法,以使大小降至更合理的水平。
有几个可用的工具:
npm install -g fixmyjs
fixmyjs <filename or folder>

一个可配置的模块,使用 JSHint (Github文档)来标记未使用的函数并进行清理。 我不确定它是否会删除 undefined 函数,而不是标记它们。虽然它是一个很好的清理工具,但似乎缺乏与后期版本的 ECMAScript 的兼容性(下面有更多信息)。还有 Google Closure Compiler,它声称可以删除死代码,但这更像是一种构建工具。如今,如果你在使用Babel等工具,可以考虑在文本编辑器中添加 ESLint,它可以触发对未使用的方法和甚至变量的警告,并且具有 --fix CLI 选项,以自动修复某些错误和样式问题。我喜欢 ESLint,因为它包含了多个插件用于替代库(例如React警告,如果您漏掉了某个属性),使您能够预先捕获漏洞。他们有一个牢固的生态系统。例如,在我的 NodeJS 项目中,我使用的配置基于Airbnb 风格指南

1
令人惊讶的是,看起来ESLint无法自动修复未使用的变量。 - loopmode

4

你需要编写一个perl脚本。不要理会上面的反对者。

这样的工具可以与只设计用于显式调用函数的库一起使用。这意味着不允许使用委托或指向函数的指针,因为它们在任何情况下都会导致难以阅读的“意大利面条代码”,并且不是最佳实践。即使它删除了一些隐藏的函数,在测试中您将发现大多数,如果不是全部。您没有发现的那些将极少使用,不值得花时间修复。不要追求完美。人们为此而疯狂。

因此,将此限制应用于JavaScript(和库)将导致页面大小和加载时间的惊人减少,更不用说可读性和可维护性了。对于删除未使用CSS的工具,如grunt_CSS和unCSS(请参见http://addyosmani.com/blog/removing-unused-css/),已经存在这种情况,并报告典型的缩小到原始大小的十分之一的减少。

这是一个双赢的局面。

值得注意的是,所有解释器都必须解决如何管理自修改代码的问题。我真不明白为什么人们要坚持不受限制的自由。正如Triptych所指出的那样,Javascript函数可以以“疯狂”的方式调用。这种疯狂的灵活性破坏了代码和数据分离的基本原则,使实时代码注入成为可能,并使任何维护代码完整性的尝试失效。结果总是难以调试的难以阅读的代码,而JavaScript的副作用——去除运行自动代码预优化和验证的能力——比任何可能的好处都要糟糕得多。
而且,你必须对自己的工作感到非常不安,才会想要故意将其从你的同事和自己身上隐藏起来。在浏览器客户端中,采用“少即是多”的方法可以取得极好的效果,迄今为止我见过的最好的例子是Microsoft Office的Access Web Forms与SharePoint Access Servcies相结合。拥有一个普及率高、紧密管理的运行时解释器客户端及其服务器端克隆的生产力是绝对惊人的。
因此,JavaScript自修改代码技术的未来是将它们重新纳入尊重“代码和数据分离”的KISS原则的行列中。

非常抱歉,但我必须微笑一下——你的优点因为拒绝承认JavaScript“疯狂”特性而大大削弱了。现代JS开发中有许多模式让我感到恼火,但动态性不在其中。导致难以管理的代码纷乱主要是开发者纪律问题,而不是语言本身的必然性。=) - Kevin Nielsen
2
我不会承认任何关于已经被认为是“疯狂”的事情的内容。这很疯狂。你无法与“疯狂”进行推理。这结束了进一步的讨论。 - Marcus Anderson

3

除非库的作者跟踪了依赖关系并提供了下载最小代码的方法[例如MooTools Core下载],否则很难识别“未使用”的函数。

问题在于JS是一种动态语言,有多种调用函数的方式。

例如,您可能有一个方法:

function test() 
{
   //
}

您可以这样调用:
   test();

   var i = 10;
   var hello = i > 1 ? 'test' : 'xyz';

   window[hello]();

这个 hello(); 会抛出一个错误,指出 'helo' 或 'xyz' 不是函数而是字符串。 - jcubic

2

我知道这是一个老问题,但UglifyJS2支持删除未使用的代码,这可能是你要寻找的。

值得注意的是,eslint支持一个名为no-unused-vars的选项,它实际上可以检测函数是否被使用。如果将函数声明为匿名函数并将其存储为变量,则它肯定会检测到(但请注意,作为变量,函数声明不会立即被提升)。

在检测未使用的函数的情况下,虽然极端,但您可以考虑将大多数函数分解为单独的模块,因为有一些软件包和工具可用于帮助检测未使用的模块。这里有sindreshorus的关于小模块思想的一小段内容,这可能与该哲学相关,但对于您的用例来说可能有些极端。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接