前言
Google Closure Compiler 是 Google Closure Tools 的一员,在 2009 年底被 Google
释出,早先,有 玉伯 的 Closure Compiler vs. YUICompressor,主要就 压缩率
上进行了对比,另外有 承玉 的 应用 closure compiler 高级模式,对 CC
的高级模式做了些介绍
本文将详细介绍 CC 的高级模式部分,更重要的是,阐述 CC 高级模式背后的思考
CC 是真正的编译器
Closure Compiler 和 YUICompressor 并不是同类产品,虽然 CC 和 YC 同样产出压缩后的 JS 文件,
但是 YC 只做了词法上的扫描,而 CC 并不只是一个 compressor 那么简单,器如其名,它是一个
compiler
对于一个 compiler,一般地,它需要做到
- 检查源文本中语法、语义、语用上的错误
- 根据分析产出物(符号表、语法树等)产出目标 / 中间代码
- 优化
代码错误一般来自三个方面:
-
语法(Syntax)
表示构成语言句子的各个记号之间的组合规律
大体上,parser / interpreter 在词法分析和语法分析阶段,产生符号表、语法树等分析产出物,
具体见编译原理教科书……语法上的错误,如:
doSomething(;) // SyntaxError: Unexpected token ;
根据语法规则,在非
for
语句中的;
意义是分隔符,而分隔符前的(
并没有配对)
,
因此报错 -
语义(Semantics)
表示各个记号的特定含义(各个记号和记号所表示的对象之间的关系)
compiler 需要根据语义分析产出中间代码,对于不产生中间代码的语言如 JS,则在运行时的
解释期间指出错误语义上的错误,如:
0 = {}; // ReferenceError: Invalid left-hand side in assignment
根据赋值运算符
=
的意义,左操作数不能为字面量,所以虽然这个赋值语句包含了必需的
左操作数、运算符、右操作数,仍然出错 -
语用(Pragmatics)
表示在各个记号所出现的行为中,它们的来源、使用和影响
语用上的错误,如:
doSomething(); // ReferenceError: doSomething is not defined
在这里直接调用了一个未定义的函数,导致出错
在一些其他场景中,虽然程序运行正确无误,但是仍然可以优化(这种优化并不是技巧上的),比如:
function doSomethingElse() {}
(function() {
return;
doSomethingElse(); // No Exception but Redundant: Unreachable code
})();
在这里,doSomethingElse 函数之前由于有 return,因此这个函数调用将永远不能执行,这种冗余代码
对整个程序来说毫无用处,可以去掉
对于 Closure Compiler 来说,它处理的对象是 js,不需要产生其他中间代码或汇编代码 / 机器码,
因此输出的还是 js,但是是经过分析的、优化后的 js;另外,它也可以选择输出 parse tree(使用
-print_tree 参数),所以,CC 的确完成了一个编译器需要实现的功能
CC 功能概述
在详细讨论 CC 的高级模式前,还是简明介绍一下功能体系
编译级别
CC 的 compilation_level 包括三个级别:
-
WHITESPACE_ONLY
只删除空白、注释
-
SIMPLE_OPTIMIZATIONS
在 WHITESPACE_ONLY 基础上将局部变量和参数转成短名称
-
ADVANCED_OPTIMIZATIONS
更加激进的重命名、移除垃圾代码、内联函数
可以看到,SIMPLE_OPTIMIZATIONS 级别的 CC,和 YC 无异,没做什么真正的编译工作,所以说,
使用了高级模式的 CC 才是四肢健全的 CC =。=
约束条件
使用 CC 有一定约束条件,这影响到我们的编码风格:
-
WHITESPACE_ONLY
- 不认可 JS 1.5 以上版本的语言特性
- 不保留注释
-
SIMPLE_OPTIMIZATIONS
- 完全禁用
with
和eval
- 字符串中引用的函数名 / 参数名不会改动
建议继续学习:
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
- 完全禁用