阅读大型 JavaScript 源码时有什么好用的工具?

2,955 阅读7分钟
原文链接: www.zhihu.com
这是一个为了阅读复杂 JavaScript 代码而开发的工具,以阅读 Vue.js 为例,在 Sublime Text 中打开后感觉非常复杂,不知道该从哪里读起:使用 lambda-view 打开后,可以看到源代码整体的轮廓其实就是一个立即调用的匿名函数:展开函数部分,值得注意的缩进风格与 Sublime Text 之类的编辑器完全不同,更易读;并且内部结构默认处于收缩状态,可以比较清楚的看到整个函数内的轮廓:点击后可以继续展开:不仅可以阅读 Vue.js 之类的前端代码,Node.js 代码也完全没问题。下面的截图来自 Node.js v4.5.0 源代码中的 node.js 文件,可以清晰的看到其整体结构也是一个立即调用的匿名函数:展开后内部结构很清楚:对于最新版本的 Node.js v6.5.0 (使用了 ES6 语法)也完全没问题,可以放心实验。该工具的安装使用方法参见项目主页:https://github.com/Jianru-Lin/lambda-view

----------------------------------------------------------------------

下述内容已不再具有意义,保留仅作历史记录----------------------------------------------------------------------

(λ-VIEW 目前已经更新到 3.0 ,本文回答的内容已经不符合目前的情况了,稍后我会做同步的更新,指明新版本的操作方法)

这个问题是我自己问的,因为这一点困扰了我很久。但是这个月初的时候,我抽了一些时间写了这个工具。它能够将复杂的 JavaScript 代码简化到极易阅读的程度。具体的原理和细节我在后面解释,我们先看看使用体验——

上图是原始的 AngularJS 源码,可以看到左侧的行号已经超过 2 万行,直接阅读这样的代码无异于划着独木舟在大海里寻找孤岛,其难度可想而知。不过当我们对其进行处理后(点击上方的 After 按钮),情况就不同了,如下图所示:

诶?2 万行代码怎么只剩下两行了?仔细一看,哦,原来这才是 AngularJS 的「真容」!整个 AngularJS 只是由一个立即调用的匿名函数(这里用 {λ} 表示),以及一行额外的处理代码组成。通常我们阅读代码的原则是——先从最外层轮廓上对代码本身获得一个直观的认识,然后再深入到具体的细节里,这能从根本上避免在刚开始就陷入细节的泥潭。这个工具正是建立在这一原则之上的。或者说,它可以帮助你更好的贯彻这一原则。(我们在稍后会用它来和其他常见的 IDE、文本编辑器进行对比,这会让你对此看得更清楚)

现在我想看看 AngularJS 中的那个匿名函数里到底做了些什么。于是我点击 {λ} 部分,紧接着就变成了下面的样子:

你会注意到:

  1. 顶部标识出了当前函数的路径 / λ-0 ( 代表顶级作用域,而 λ-0 是我们目前所处于的位置,它是顶级作用域下的第 0 号匿名函数)
  2. 左侧列举出了当前作用域内定义的子函数
  3. 右侧的源代码区域出现的不是原始的 JavaScript 代码,而是经过美化的——花括号都不见了,而是改为使用缩进;分号都去除了;等等
今天先写到这里,后续会补上

待续1:这个工具是怎么实现的?待续2:和 IDE 相比这个工具有什么优缺点?待续3:后续会增加什么功能?

我强烈建议你亲自上 喵德利 (我已经部署好了) 试一试,因为有些细节如果由我在此描述难免太冗长,但你一旦自己亲身体验,就会立刻体会到。

2014-09-23 更新

这个工具是怎么实现的?

这个工具看起来很复杂。这可能会产生出让人钦佩的误解。事实上我确实做了一些工作,但并不像看起来那么艰巨。如果列举一下,整个工作实际上是由以下部分合力完成的:

  1. ACE 编辑器,提供了代码编辑支持
  2. Esprima 解析器,能够将 JavaScript 源代码解析为 AST(抽象语法树)
  3. jQuery 库,帮助我便捷的进行 DOM 操作
  4. Bootstrap 库,简化了界面布局和组织的工作
  5. 我自己的代码,实现了最终的功能
可见我确实做了一些事。但更主要的工作还是由 1-4 的部分完成的。如果你觉得这个软件很不错,或许上述库的作者们更应当被感谢。

特别值得一提的是 Esprima,它是这整个软件所用到的核心部件。我首先使用它来完成 AST(抽象语法树)的构建,紧接着,我会遍历这颗 AST 树,然后重新按照我想要的方式生成一颗 DOM 树。这样就完成了一次重渲染,将原始的 JavaScript 代码改写为了更简洁的形式。

当然,在遍历 AST 树的过程中也要做一些简单的分析工作。否则就无法实现将子函数抽取出来这样的操作了。不过这个分析操作实在很简单,也没什么可谈的。后续我会在分析过程上做很多工作,实现更多实用的功能。详细的情况可以参见后续的路线图部分。

和 WebStorm 之类的 IDE 相比有什么优缺点?

术业有专攻。尽管 WebStorm 之类的 IDE 提供了强大的「编辑」功能。但是从实践的角度来说,这些编辑器在用于阅读代码时还存在诸多不足。

比较典型的一点是,编辑器总是老老实实的把原始的排版格式呈现出来。而实际上我们需要的是更加紧凑、标准、一致、适度简化后的呈现。例如下面的对比图所示:

上图是同一段代码(选自 AngularJS)处理前后的对比。我们可以注意到一些细节:

  1. 分号被移除了
  2. 花括号被移除了(改为用缩进来表示层次关系)
  3. 行间距被适当增大了,看起来没那么拥挤了
  4. 函数调用时,前后括号和参数之间都增加了空白
  5. 最重要的是,代码从 6 行变成了 4 行,缩短了
任何程序员——任何真正尝试过阅读陌生的大型项目的程序员,应该都能够理解这种形式简化将带来的实际好处。它让你更加专注于代码的逻辑,而不是形式。

我们的代码阅读软件能够理解代码的结构,并能够将其转换为更加简洁的形式,这一点有时候能给我们带来意想不到的帮助——例如阅读在 web 环境下那些被压缩过的代码。下图的代码截取自某站点:

这样的代码是经过压缩的——删掉了空格、缩进、换行等字符并改写了变量名等——阅读几乎是不可能的。但有些人却必须要从这样的代码里找出感兴趣的东西,比如大家熟悉的白帽子安全人员。

相对一般的 IDE,专门的代码阅读软件在处理这样的问题上更加得心应手。

综上所述,WebStorm 之类的软件在「编辑」、「项目管理」方面更加强大,但在「阅读」、「分析」方面,专门的代码阅读工具会更加方便。

未来的发展路线图——后续功能开发计划

(待续)