ecmascript解析器-UglifyJS 有一个很好的 JavaScript 解析器

2023-08-23 0 3,981 百度已收录

我仍在为 Jscex 寻找一个好的 JavaScript 解析器,我之前使用过 Narcissus 并写过有关它的文章。 但不幸的是,Narcissus 使用了 SpiderMonkey 的扩展,因此它不是用 ECMAScript 3 实现的,不能在 IE 8 等浏览器中使用。目前 Jscex 在 NarrativeJS 中使用旧版本的 Narcissus,但我不喜欢 AST结构它的输出。 我在使用过程中也发现了一些中间函数的bug。 。 最近接触了UglifyJS,发现它的解析器相当不错,性能比Narcissus高很多,所以在这里给大家介绍一下。

介绍

UglifyJS是一个JavaScript压缩器,效果比Google Closure Compiler更好。 对于现代 JavaScript 压缩器来说,仅仅消除空格和压缩局部变量是不够的,还需要理解代码的语义并用更小的代码替换(Uglify 的帮助页面上有很多描述)。 这可能需要 JavaScript 解析器。 UglifyJS是基于NodeJS开发的,但它可以运行在支持CommonJS模块系统的各种JavaScript引擎/平台上。 如果没有CommonJS,只需删除与导出相关的代码即可。

JavaScript解析器的作用自然就是将JavaScript代码分解为AST,然后你可以根据AST做很多有趣的事情。 相同的 AST 在视频内存中可以有不同的表示形式。 例如ecmascript解析器,我之前提到过,我不喜欢 Jscex 目前使用的旧版本的 Narcissus。 一个重要原因是它的AST结构不够友好(最新的Narcissus还不错)。 另外,虽然它提供了一些中间级的功能,比如标记每个元素在源代码中的位置,以便用户可以根据getSource方法直接获取其对应的源代码——可惜这个功能有bug测试后。 促使我也遍历完整的 AST。

UglifyJS 的 JavaScript 分词器和解析器存储在源代码的 parse-js.js 文件中,从 parse-js 项目移植而来ecmascript解析器,是 Common Lisp 中的通用实现。 现在您应该能够猜测它输出的 AST 的表示形式。 没错,它是一个“表”,用 JavaScript 表达,它是字段中的字段。 我写了一些简单的代码以低格式输出它,你可以在这里简单地尝试 UglifyJS 解析器。 这个输出看起来很简单,但是对于 Jscex 来说已经完全足够了。

使用

打开parse-js.js文件,你会看到如下代码:

/* -----[ Tokenizer (constants) ]----- */var KEYWORDS = array_to_hash([
...
]);

var RESERVED_WORDS = array_to_hash([
...
]);

...

function parse($TEXT, exigent_mode, embed_tokens) {
...
}

/* -----[ Exports ]----- */

exports.tokenizer
= tokenizer;
exports.parse
= parse;
exports.slice
= slice;
exports.curry
= curry;
exports.member
= member;
exports.array_to_hash
= array_to_hash;
exports.PRECEDENCE
= PRECEDENCE;
exports.KEYWORDS_ATOM
= KEYWORDS_ATOM;
exports.RESERVED_WORDS
= RESERVED_WORDS;
exports.KEYWORDS
= KEYWORDS;
exports.ATOMIC_START_TOKEN
= ATOMIC_START_TOKEN;
exports.OPERATORS
= OPERATORS;
exports.is_alphanumeric_char
= is_alphanumeric_char;
exports.set_logger
= function(logger) {
warn
= logger;
};

UglifyJS是基于CommonJS模块机制编译的。 这个文件可能是一个模块,通过exports暴露到外部。 如果我们将它作为普通的 JavaScript 文件引入到浏览器中,显然会报“export undefined”异常。 理论上,如果定义了一个exports对象,甚至消除了与exports相关的代码,就可以正常使用parse方法。 不过,这样做也有一个严重的问题,那就是根对象的“污染”太严重了。 比如在浏览器中,所有的函数和定义都出现在窗口上,同时引入了一些其他的泛型类型,造成了冲突。 几率相当高。

所以我们必须对代码进行一些修改。 幸运的是,在 JavaScript 中解决这种“范围”问题非常容易。 例如,我将 parse-js.js 的代码包围起来,如下所示:

var UglifyJS = {};
(
function (exports) {
/* original code here */
})(UglifyJS);

这解决了范围问题,现在我们可以访问 UglifyJS 对象上的 KEYWORDS 集合和解析以及其他成员。

表现

然后我们来谈谈性能。 JavaScript 仍然被认为是一种低效的语言——这也许是一种误导的观点。 事实上,就语言设计而言,JavaScript 比 Python 和 Ruby 更快,但由于历史原因,各大浏览器并没有太重视。 然而,情况早已发生了变化。 在V8的带领下,现代JavaScript引擎的执行速度已经超越了最快的Python和Ruby实现。 话不多说,现在我们来对比一下UglifyJS解析器和Narcissus在各种浏览器中的性能。

测试页面在这里,大家可以自己尝试一下。 测试场景是用两者解析Narcissus的源码十次——大约1500行未压缩的JavaScript代码(值得一提的是我尝试了很多压缩的代码,比如jquery-min.js,它们可以是使用 UgilifyJS 可以正常解析,但 Narcissus 无法解析)。 我使用了公司配置的两台标准工作电脑,测试了IE、Chrome和Firefox各两个版本的总共6个浏览器。 我会对每个浏览器运行多次测试,删除误差较大的结果,并取中间值。 遗憾的是,由于条件所限,两台机器的操作系统不同。 虽然我认为不会对结果产生什么影响,但是如果你够认真的话,不妨自己评估一下。

首先我在Win 7下测试了Chrome 10、FireFox 3和IE9,结果如下:

对于 UglifyJS,Chrome 10 表现最好,IE 9 稍慢,Firefox 3 则比前两者长几倍。 对于 Narcissus 来说,IE 9 表现最好,仅为 Chrome 10 的五分之一,而与 Firefox 3 相比,则是一个数量级的领先者。 有趣的是,两个解析器在 Chrome 10 和 Firefox 3 下的持续时间大约为 1 到 10,而在 IE 9 下差异几乎相同。

然后Win XP下的Chromium 12、Firefox 4和IE 8,结果如下:

对于 UglifyJS 来说,Chromium 12 的性能依然抢眼,比 Firefox 4 好很多,但 Narcissus 的情况却恰恰相反。 还可以看出,IE 8 的 JavaScript 引擎性能完全逊于其他浏览器,但与 IE 9、Firefox 4(以及旁边的 Safari)类似,即 UglifyJS 和 Narcissus 的持续时间并不多不同的。

为了方便观察,我把两次测试的结果放在一起(Chromium 12非官方版本除外):

总体而言,Chrome 10、IE 9和Firefox 4是第一军。 IE 9 在 UglifyJS 上稍逊于 Chrome 10,但在 Narcissus 上优势明显; Chrome 10 在 UglifyJS 上表现最好,但在 Narcissus 上落后于 IE 9 和 Firefox 4; Firefox 4实际上并不是“最好的”,但差别也不是太大。 至于IE 8和Firefox 3,确实在JavaScript执行效率方面早已落后于这个时代。 必须承认,如今的浏览器大战,确实让各方素质有了很大的提高。

另外,我还在公司的iMac上测试了Chrome 10、Firefox 3和Safari 5,结果如下:

虽然浏览器的性能不同,差距也不同,但可以肯定的是,UglifyJS解析器的性能确实高于Narcissus。 因此,我将在接下来的几天内将 Jscex 中当前使用的 Narcissus 替换为 UglifyJS。

总结

由于后端开发和 JavaScript 的流行,越来越多的人开始用 JavaScript 做有趣的事情。 我实在不喜欢现在很多所谓的后端做法,纠结于大量的hack和各种浏览器的性能,甚至JavaScript的某种写法性能更高——比如据报道对于字符串连接操作而言,a += b 比 a = a + b 具有更高的性能(反之亦然)。 在我看来,这种东西是最没用的,知道了又如何? 随着浏览器的更新,这些“体验”立刻就没用了。

这就是为什么我喜欢玩JavaScript,但不想做后端开发,尤其是HTML和CSS。 同样的,IE 6这样的浏览器在我眼里也是必须杀掉的东西。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 ecmascript ecmascript解析器-UglifyJS 有一个很好的 JavaScript 解析器 https://www.wkzy.net/game/143890.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务