`
roc08
  • 浏览: 224488 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

YUICompressor和 google closure compiler使用总结

阅读更多
YUICompressor和 google closure compiler使用总结
YUICompressor是yahoo提供的进行js、css压缩混淆的工具,使用java编写。
1. 手工压缩单个文件
参考文档:http://www.36ria.com/3948
(1)配置java运行环境
在安装YUI Compressor前,先要确保你的机子安装了JDK,并且添加了java必要的环境变量 (主要是path)。
(2)安装YUI Compressor
下载地址http://www.36ria.com/wp-content/plugins/download-monitor/download.php?id=211
运行压缩包的install.cmd,如果出现“rundll32 不是内部或外部命令,也不是可运行的程序或批处理文件”,说明java环境配置有误,请返回第一步。
安装完成后,会在你的系统右键菜单增加一个压缩文章(只有在右击文件的时候才会出现哦)。接下来以压缩包中的test.js为例。
3.YUI Compressor简易操作
右击test.js,点击“process with YUI Compressor”,稍等片刻,就会生成一个test-min.js文件
2. 结合ant批量压缩
定义属性:源码文件路径,css路径,yuicompressor.jar的路径
1.	<property name="uploader.dir" location="${current.dir}/../uploader/"/>
2.	    <!--css路径-->
3.	    <property name="css.path" location="${uploader.dir}/uploader.css"/>
4.	    <!--yuicompressor程序路径-->
5.	    <property name="yuicompressor.path"location="${current.dir}/yuicompressor/yuicompressor.jar"/>
任务1:压缩uploader/uploader.css到uploader-min.css
1.	<target name="minify-css">
2.	        <apply executable="java" verbose="true" dest="${uploader.dir}/../"  failonerror="true"parallel="false">
3.	            <fileset dir="${uploader.dir}" includes="uploader.css"/>
4.	            <arg line="-jar"/>
5.	            <arg path="${yuicompressor.path}"/>
6.	            <arg line="--charset gbk"/>
7.	            <arg value="--type"/>
8.	            <arg value="css"/>
9.	            <arg value="-o"/>
10.	            <targetfile/>
11.	            <mapper type="glob" from="*.css" to="*-min.css"/>
12.	        </apply>
13.	    </target>

minify-css任务执行yuicompressor.jar,apply标签(dataType)用于执行java程序。留意dest属性,用于指定输出目录,是必须的。
子元素fileset用于提取源文件,这里只需要uploader/uploader.css这个文件。
arg标签最后会合并成1行命名。
• -jar:yuicompressor.jar路径
• –charset:输出文件编码
• –type:文件压缩类型,css或js
• -o:输出路径
代码中的mapper标签(dataType)的用途是什么?
mapper定义了一组源文件和一组目标文件的关联方式。共有三个关键属性:
• type:关联方式,值有glob、identity、flattern、merge、regexp
• from:源文件
• to:目标文件
关键看下type属性,当值为glob时,表示基于简单的通配模式(比如*、**)确定文件名。大多数情况glob属性已经够用了。
yuicompressor需要使用mapper来确定批量输出文件规则, demo代码很简单,将*.css输出成*-min.css。
任务2:压缩uploader目录下的js文件为*-min.js
1.	<!--压缩js-->
2.	    <target name="minify-js">
3.	        <apply executable="java" dest="${uploader.dir}/../">
4.	            <fileset dir="${uploader.dir}" includes="*.js"/>
5.	            <arg line="-jar"/>
6.	            <arg path="${yuicompressor.path}"/>
7.	            <arg value="-o"/>
8.	            <targetfile/>
9.	            <mapper type="glob" from="*.js" to="*-min.js"/>
10.	        </apply>
11.	    </target>


Google closure compiler使用
ant执行closure-compiler与yui-compressor基本上一样。closure-compiler的js压缩比yui-compressor强悍,一般使用closure-compiler压缩js文件,使用yui-compressor压缩css文件。接下来来看下closure-compiler的调用语法。
任务:合并几个js文件,并压缩合并后的文件
合并uploader/base.js、uploader/render.sj、uploader/renderUploader.js为uploader.source.js,并压缩成uploader-min.js。
1.	<target name="closure" depends="concat,minify-js-closure">
2.	 
3.	  </target>
4.	    <!--合并js-->
5.	    <target name="concat">
6.	        <concat destfile="${uploader.dir}/../uploader.source.js">
7.	            <path path="${uploader.dir}/base.js"/>
8.	            <path path="${uploader.dir}/render.js"/>
9.	            <path path="${uploader.dir}/renderUploader.js"/>
10.	        </concat>
11.	    </target>
12.	    <!--使用closure压缩js-->
13.	    <target name="minify-js-closure">
14.	        <apply executable="java" verbose="true" dest="${uploader.dir}/../" failonerror="true"parallel="false">
15.	            <fileset dir="${uploader.dir}/../" includes="**/*.js"/>
16.	            <arg line="-jar"/>
17.	            <arg path="${closure.path}"/>
18.	            <arg line="--charset gbk"/>
19.	            <arg value="--warning_level"/>
20.	            <arg value="QUIET"/>
21.	            <arg value="--js"/>
22.	            <srcfile/>
23.	            <arg value="--js_output_file"/>
24.	            <targetfile/>
25.	            <mapper type="regexp" from="^(.*)\.source\.js$" to="\1-min.js"/>
26.	        </apply>
27.	    </target>

关于concat任务标签,不再累述。重点看下minify-js-closure这个任务。
closure-compiler的调用参数与yui-compressor有一些不同,输出不是使用-o参数,而是使用–js_output_file。
mapper标签中type=”regexp”使用正则规则来匹配源文件和目标问题。
PS: (.*)为建立分组捕获,to=”\1-min.js”中的\1,使用该分组。
附:closure-compiler介绍:
CC 是真正的编译器
  Closure Compiler 和 YUI Compressor 并不是同类产品,虽然 CC 和 YC 同样产出压缩后的 JS 文件,但是 YC 只做了词法上的扫描,而 CC 并不只是一个 compressor 那么简单,器如其名,它是一个compiler。
CC 功能概述
  在详细讨论 CC 的高级模式前,还是简明介绍一下功能体系。
  编译级别
  CC 的 compilation_level 包括三个级别:
1. WHITESPACE_ONLY
只删除空白、注释。
2. SIMPLE_OPTIMIZATIONS
在 WHITESPACE_ONLY 基础上将局部变量和参数转成短名称。
3. ADVANCED_OPTIMIZATIONS
更加激进的重命名、移除垃圾代码、内联函数。
  可以看到,SIMPLE_OPTIMIZATIONS 级别的 CC,和 YC 无异,没做什么真正的编译工作,所以说,使用了高级模式的 CC 才是四肢健全的 CC 。
  约束条件
  使用 CC 有一定约束条件,这影响到我们的编码风格:
1. WHITESPACE_ONLY
• 不认可 JS 1.5 以上版本的语言特性
• 不保留注释
2. SIMPLE_OPTIMIZATIONS
• 完全禁用 with 和 eval
• 字符串中引用的函数名 / 参数名不会改动(CC 不改动所有字符串)
3. ADVANCED_OPTIMIZATIONS 模式下的约束放到下文详述
  注解
  Annotations 也是 CC 的重要组成部分,使用 JSDoc 风格,用以辅助高级模式下的编译,下文详述。
  使用 CC 高级模式
  在 CC 下,启用高级模式的方法是加入参数 --compilation_level ADVANCED_OPTIMIZATION。
  作为一个 compiler,CC 的高级模式下,额外的优化政策是:
1. 更激进的重命名,如 obj.property 改为 a.b,将深度过高的命名空间平坦化等;
2. 移除垃圾代码,如删除未被调用的方法定义,警告逻辑死角(return 后的语句等);
3. 将函数内联,如 a call b, b call c,a(),那么直接执行 c()。
  要达到高级模式的预期优化效果,开发者必须对自己做一些约束,因为 js 是弱类型、动态性的。否则js 的这种灵活将使 compiler 无能为力。
  总体上,这种约束包括限定某些 js 编码风格,以及使用相应的 JSDoc 注解。
  以下详述具体的约束以及代码的检查 / 优化效果:
  强类型的模拟
• @param 和 @type 中定义的类型会在编译期间得到检查,同样避免了在运行时检查,提高性能。
• @const 标记常量,当常量被写(重新赋值)时会报错。
• 模拟枚举,将同类可枚举常量定义为一个对象字面量,使用 @enum 标记:
var STATUS = { LOADING: 3, COMPLETE: 4};
编译结果中 STATUS.LOADING 会被直接替换为 3,其实完全模拟了 C 等语言中的枚举。
• 使用 @constructor 标注函数为构造器,它仅能被实例化,而不可用作普通方法,甚至是工厂方法,CC 会确保构造器被合法使用,否则报错。这样确保开发者不必在运行时判断,构造器函数到底以怎样的形式被调用。
• 在表达式中也可以使用 @type 来限定类型,这对于 JSON 特别有用,如
var data = /** @type {UserModel} */({ firstName : 'foo', lastName : 'bar'});
在这里 UserModel 是个构造器,也可以使用 @typedef 来自定义复杂的数据类型。
  域可见性的模拟
• 使用 @private 标注私有域,私有域被外部引用会报错。开发者也可以按照“国际惯例”给私有域加上_ 前缀或后缀,以提醒自己 / 协作者这是一个私有域,@private 注解用来告诉 CC;这样,开发者可以不必使用诸如老道的“模块模式”等技巧来真正地隐藏私有变量,将检查工作丢给CC,让开发尽可能朴实简单。
• 类似有 @protect
  类系统的模拟
• 使用 @extends 标注继承关系,继承体系会被优化。
• 使用 @interface 标注接口,接口是类似 function ThisIsAInterface(obj) {}的 函数体为空的构造器定义,编译后将移除其相关代码。同时,标注 @implements 的构造器必须实现implemented 的接口的所有方法(正如其他 OO 语言一样),否则,CC 报错。这同样简化了接口 / 实现的约束,靠 CC 来保证实现关系的可靠性。
  条件编译的模拟
• 使用 @define 标记状态开关,适用于调试 logger 等 开发 / 发布 状态需要分离的模式。
可以在编译时指定参数来标识 define 参数的状态。这其实就是一个条件编译,真给力……
  对象平坦化及属性名缩减
• 对象属性会被编译为单变量,比如 foo.bar to foo$bar,这种标记方法看起来很像 java 中被编译出来的内部类~~之后 foo$bar 被进一步缩短。对象之所以能被平坦化是因为在 js 中对象可以看做是一群引用 / 原始数据类型的容器。
• 但是,js 对象实际上更复杂,所以被平坦化后会带来一些副作用,比如如果在对象(字面量)中使用 this 指针,则编译后的结果会导致 this 指向错误。所以 Google 建议仅在 constructor 和 prototype methods 中使用 this,这意味着,在所谓类单例(对象字面量)和类的静态方法(绑定到constructor 上的函数)中都避免使用 this 指针。
• 在缩减对象属性 / 方法的名称长度时,有另外一个注意点,那就是必须始终使用 dot syntax(.运算符),而不使用 quoted string([] 运算符),除非索引名是一个变量。这是因为 CC 始终不处理字符串中的内容,所以,var o = { longName: 0 }; o["longName"] 会被翻译为var a = { b: 0 }; a["longName"] 导致出错。实在想使用 quoted string,则在定义的时候也要使用 quoted string。
• 对于全局变量,如果出现以 window.property 的形式引用的,必须始终定义为 window.porperty 形式:
window.property = 1;var property = 1; // wrong!
否则也会杯具,CC 可不会 window.property 翻译为 window.a。
  垃圾代码的移除
• 一个函数声明却未被调用时,默认地,声明体将被干掉。
• 在这种机制下,如果一个方法是以 for in 的形式调用的,那么原方法也会被干掉,因为这种动态特征使得 CC 无法清楚方法是否确实在 for in 的时候被调用了。
• 对于一些 unreachable 的代码,CC 将报警告。
• 如果要产出一份被调用的公共接口,例如库,使用称作 export 的方法将函数导出,防止函数定义被
CC 回收。具体的做法是将函数绑定到某个容器,比如:
function displayNoteTitle(note) { alert(note['myTitle']);}// Store the function in a global property referenced by a string:window['displayNoteTitle'] = displayNoteTitle;
对于需要 export 的函数,均使用 quoted string 风格。
  背后的思考
  根据以上高级模式优化的行为分析可知,CC 附加给开发者的约束主要有:
1. 强制以强类型的静态语言风格编写 js,将关注点从运行时的动态技巧转移到组织代码、编写逻辑本身。而可能由弱类型系统和动态特征产生的问题和风险则交给 CC,即通过开发者与 CC 达成一种编码约定而规避掉。
2. 严格要求区分面向开发者的代码和面向机器的代码。
虽然不像 C 等语言会编译产生目标代码,但是 CC 在一定程度上也生成了面向机器的 js,包括压缩空白、缩减标识符、条件编译和冗余代码去除。这和第一点其实是一脉相承的,同样要求开发者将关注点转移到开发本身。
3. 使用规范化的接口方式。
这不仅包括要求开发者使用恰当的 annotation(extend, interface, …),同时也给整个 OO-JS 打下了一个框架,开发者必须使用同样的模式进行 OO 编码。另外,要求使用 export 技术统一导出公共接口更强化了这一点。总之,这一点进一步限定了开发者的编码风格,但是带来的好处是明显的:可读、可控、一致性。
  曾经有读过 Closure Library 源码的同学评论道:
Google 根本不懂怎么写 javascript!代码里面各种冗余,并且充满了 java 的味道!
  当时确实也有这种感觉,比如 Google 把 if(foo) 写作 if(foo != undefined) 等等。
  Javascript 固然充满了丰富的动态特征,而且很多特性非常优雅,能够让代码简洁精悍,或者构造出一些令人惊叹的技巧,但是也会产生一些副作用:
• 首要的问题是可读性,静态的东西容易一目了然,动态的东西需要经过一番运算才能得出结论。比如 js 中的极晚绑定,再比如标识符运行时重写。
• 其次的问题是执行性能。一个比较经典的众 js 工程师都在使用的技巧就是“模拟函数重载”——
在函数体内判断 arguments 的特征,从而对应给出不同的逻辑。由于缺乏强类型,js 本身不能具备真正的重载,但是运行时的判断在带来灵活性的同时,必然会多出很多模拟重载的逻辑,降低性能。
  在今年的 D2 大会上,Hedger 同学指出,大多数 js 开发者像是个 ninja(忍者),他们身怀绝技、神鬼莫测,单兵作战还可以,但是一旦碰到 army(军队,比如 Google 团队这样的 )就是个悲剧。
  我比较欣赏这个比喻,大团队要良好地协作,必需遵循一定的规范和限制,优先保证可读性和一致性,与此同时失去的是奇技淫巧、自由灵活。所以采用何种编程风格、理念,需要具体问题具体分析…………
  至少,目前 CC 提供了一个好的思路,它的高级模式推崇的编程风格也是很值得尝试、借鉴的。
  最后附上 CC 的常用命令选项……选项实在是有够多……
  CC 常用命令选项
• –charset VAL 对所有文件定义的编码格式
• –compilationlevel [WHITESPACEONLY | SIMPLEOPTIMIZATIONS | ADVANCEDOPTIMIZATIONS]
设定编译级别
• –debug 开启 debug 选项
• –define (–D, -D) VAL 设定文件中使用 @define 标注的开关值,即条件编译
• –externs VAL 编译代码需要调用未编译的代码时,使用它
• –formatting [PRETTYPRINT | PRINTINPUT_DELIMITER] 格式化输出
• –js VAL 输入文件,多指定多个,将会被合并
• –jsoutputfile VAL 输出文件,如果不指定的话,直接输出到 standard output 流
• –module VAL 定义模块
• –output_manifest VAL 打印编译文件清单
• –print_tree 打印语法分析树
• –warning_level [QUIET | DEFAULT | VERBOSE] 设定报错模式
参考文献:
http://developer.yahoo.com/yui/compressor/
http://fengjunoo.iteye.com/blog/1168741
http://www.36ria.com/4644
http://www.cnblogs.com/yangligogogo/articles/1952755.html
ant开发及整合应用详解

分享到:
评论

相关推荐

    JavaScript代码压缩工具UglifyJS和Google Closure Compiler的基本用法

    网上搜索了,目前主流的Js代码压缩工具主要有Uglify、YUI Compressor、Google Closure Compiler,简单试用了UglifyJS 和Google Closure Compiler 两种工具的基本用法,需要的朋友可以参考下

    yii2的js 压缩工具 compiler.jar

    jsCompressor 和 cssCompressor 选项指定控制台命令或PHP回调函数来执行 JavaScript 和 CSS 合并和压缩, Yii 默认使用 Closure Compiler 来合并 JavaScript 文件, 使用 YUI Compressor 来合并 CSS 文件

    EclipseMinifyBuilder:Eclipse的增量生成器,可最小化CSS和JavaScript

    Eclipse Minify插件 用于减少CSS和JavaScript的增量生成器。 安装 您可以通过其更新站点安装插件。... 0.9.2版支持YUICompressor和Google Closure Compiler。 0.9.5版支持使用Google Closure编译器生成源地图。

    guard-mirror:一个 CoffeeScript、Stylus 和 Jade(HTML 和 JST)保护,它在另一个位置(publicwwwetc...)镜像你的源文件(.coffee.styl.jst.jade.html.jade)

    Google Closure Compiler 用于 JS 和 YUI Compressor for CSS。 Jade -&gt; HTML 文件会自动收缩包装。 链轮用于文件请求和连接,因此可以使用所有相同的链轮语法。 我创建它是为了帮助 PhoneGap/Cordova 开发,它的...

    Java项目源码经典实用——提高必备【必学必看】

    JSCSS压缩工具 YUI Compressor.zip JSON查询语言 Jaql.rar JSON类库 Flexjson.zip JSP标签 Noka Tag.rar JS和CSS压缩混淆 JsCompressor.rar js文件压缩工具 Closure Compiler.rar jviolajones(人脸检测算法)....

    前端代码源码一键压缩工具(shell/bat)

    closure-compiler、htmlcompressor、yuicompressor压缩js、css、html文件;把要压缩的代码跟下载解压后的Tool文件夹同层,前端代码源码文件一键压缩工具(shell/bat);Windows执行Html5Shell.bat、Linux MacOX执行...

    编写可维护的javascript(英文)

    17.1.1 使用YUI Compressor精简代码 17.1.2 用Closure Compiler精简 17.1.3 使用UglifyJS精简 17.2 压缩 17.2.1 运行时压缩 17.2.2 构建时压缩 第18章 文档化 18.1 JSDoc Toolkit 18.2 YUI Doc 第19章 ...

    编写可维护的JavaScript(中文)

    17.1.1 使用YUI Compressor精简代码 17.1.2 用Closure Compiler精简 17.1.3 使用UglifyJS精简 17.2 压缩 17.2.1 运行时压缩 17.2.2 构建时压缩 第18章 文档化 18.1 JSDoc Toolkit 18.2 YUI Doc 第19章 ...

    node-minify:轻量Node.js模块,可压缩javascript,css和html文件

    一个非常轻巧的Miner Node.js模块。产品特点它允许您压缩JavaScript,CSS和HTML文件。...require ( '@node-minify/core' ) ;...// Using Google Closure Compilerminify ( { compressor : gcc , input : 'foo.js' ,

    java开源包8

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包1

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包11

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包2

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包3

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包6

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包5

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包10

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包4

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包7

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包9

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

Global site tag (gtag.js) - Google Analytics