Uglify是一个通用的JavaScript分析器/检查机/美化工具。
This package implements a general-purpose JavaScript parser/compressor/beautifier toolkit.
编译器或解析器(tokenizer/parser)从JS代码生成一个抽象的语法树。你能遍历这个AST(abstract syntax tree)以了解更多有关的代码,或做不同的操作。这部分由parse-js.js实现。
Process.js检查和操作由分析器(parser)生成的AST,提供一下功能:
l 从AST重新生成JavaScript代码。可选自动缩进,你可以使用这个如果你想美化一个已经被检查的程序,这样你就可以检查源码了。
l 缩短变量名(通常缩成单个字符)。我们的检查机(mangler)将会对代码进行分析,并生成正确的变量名。
l 各种小的优化可能会导致更快的代码,但是一定会导致更少的代码量。在可能的情况下,我们做到以下几点:
² foo[""bar] => foo.bar
² 删除块括号{}
² 合并连续的var声明
² 解决简单的常量表达式:1+2*3 => 7。我们只在能占用更少字节的情况下做替换;例如 1/3将会转换为0.333333333333,所以在这种情况下我们不会取代它。
² 块中的连续的陈述将会合并成一个序列。
² 各种if语句优化:
if(foo) bar();else baz(); ==> foo ? bar(): baz();
if(foo) bar(); ==> foo&&bar();
if(!foo) bar(); ==> foo||bar();
if(foo) return bar(); else return baz(); ==> return foo?bar():baz();
² 删除一些不可达的代码(跟在return,throw,break或continue语句后的代码,除了函数/变量声明)。
² 扮演一个限制版的预处理器,让你安全地用给出的值替换指定的全局符号。当结合这上面的优化可以让UglifyJS操作更像一个编译的过程,当某些符号被常量代替,整个代码块可能被优化掉。
安装:npm install uglify-js -g
检查(compress)js,命令uglifyjs + 文件名 -o 输出文件名
若不加-o参数,则检查后内容输出到屏幕
美化(beautify)js,和检查相反的过程,也就是解检查。命令:uglifyjs + 文件名 + -b
使用方法:
uglifyjs [input files] [options]
uglifyjs -help 帮助信息
常用参数:
-o, --output 指定输出的文件,默认情况下为命令行
-b, --beautify 美化代码
-m, --mangle 改变变量名称(默认不改变变量名称)
-r, --reserved 保留变量名称,不需要被-m参数改变的变量名
-c, --compress 检查参数
-d, --define 全局定义
--comments 用来控制注释的代码
Mangler options 变量名检查器选项(用逗号分开)
sort 给最常使用的变量分配较短的名称。(默认不可用)
toplevel 检查在顶级范围声明的变量(默认不可用)
eval 在使用eval或when的链检查名称
当使用检查选项时(-m),但是你想让几个变量名不被检查,你可以声明这些变量用--reserved(-r)传递一个逗号分隔的名称列表。例如:
uglifyjs ... -m -r '$,require,exports'
require, exports, $ 三个变量不会被改变
Compressor options
传递--compress或-c时才能使用下面的选项
dead_code 删除死代码
properties 重写属性用点标的形式,foo["bar"] => foo.bar
warnings 显示warning当删除不可达的代码或这没用的声明等情况时。
……
Conditional compilation
你可以使用--define(-d),以声明uglify假定是常量的全局变量。
if(DEBUG){
console.log("hehe");
}
在开发过程中使用如上所示的调试代码,完成开发时一条一条删除比较费功夫,而且不一定删除干净。在uglifyjs中传递--define DEBUG=false后,if条件句的花括号{}内的代码就不会被执行,就成了死代码(dead code),uglifyjs会删除死代码,这样的话,文件中所有的调试代码就会被删除。如下图:
这样使用要求DEBUG不能在文件中定义过。可以在调试时将DEBUG定义为全局变量
var DEBUG=true,调试完毕后将这条定义语句删除或注释掉,这样就可以使用上面方法去除调试语句了。
Beautifier options 美化选项
indent-level 缩进长度,默认为4
indent-start 代码缩进开始的位置,默认为0,即对代码整体进行缩进
inline-script 转义js代码字符串变量中的script标签
……
Keeping copyright notices or other comments 保留版权提示或其他注释
传递--comments默认会保留JSDoc风格的注释它包含“@preserve”,"@license"或者
“@cc_on”。传递--comments all 保留所有的注释,或者用一个JavaScript正则表达式来值保留匹配正则的注释。例如,--comments '/foo|bar/' 将会只保留包含“foo”或“bar”的注释。
https://npmjs.org/package/grunt-contrib-uglify
js-contrib-uglify的使用
Basic compression 常规压缩
这个配置将会压缩和碾压(mangle压缩变量名)输入的文件用默认的选项
grunt.initConfig({
uglify: {
my_target: {
files: {
'dest/output.min.js' : ['src/input1.js','src/input2.js']
}
}
}
});
No mangling 不碾压
指定 mangle: false阻止改变你的变量和函数名。
grunt.initConfig({
uglify: {
options: {
mangle: false
},
my_target: {
fiels: {
'dest/output.min.js': ['src/input.js']
}
}
}
})
Reserved identifiers 保留标识符
grunt.iniConfig({
uglify: {
options: {
mangle: {
except: ['jQuery','Backbone']
}
},
my_target: {
fiels: {
'dest/output.min.js': ['src/input.js']
}
}
}
});
Beautify 美化
指定beautify:true来美化你的代码用来调试和修改目的。你可以传递一个对象手动的配置任何输出选项。
1 grunt.initConfit({ 2 uglify: { 3 my_target: { 4 options: { 5 Beautify: true 6 }, 7 files: { 8 'dest/output.min.js': ['src/input.js'] 9 } 10 }, 11 my_advanced_target: { 12 options: { 13 beautify: { 14 80, 15 beautify: true 16 } 17 }, 18 files: { 19 'dest/output.min.js': ['src/input.js'] 20 } 21 } 22 } 23 });
Banner comments 标识信息
在这个例子中,运行grunt uglify: my_target 将会在文件头插入一个标识,这个标识是通过将配置对象内嵌到banner模板字符串。这里,这些属性是从package.json文件引入的,再加上今天的日期。
提示:你不必用外部的json文件。在config中创建pkg对象也是可以的。
grunt.initConfit({
uglify: {
options: {
Banner: '/* <%= pkg.name %> -v <%= pkg.version %> - */' + '<%= grunt.template.today("yyyy-mm-dd")%>';
},
my_target: {
files: {
'dest/output.min.js': ['src/input.js']
}
}
}
});
Conditional compilation 条件编译
uglifyjs的条件编译通常用来移除调试代码块。
1 grunt.initConfig({ 2 uglify: { 3 options:{ 4 compress: { 5 Global_defs: { 6 "DEBUG": false 7 }, 8 dead_code: true 9 } 10 }, 11 my_target: { 12 files: { 13 'dest/output.min.js': ['src/input.js'] 14 } 15 } 16 17 } 18 });
Grunt-contirb-jshint的使用
Wildcards 通配符
grunt.initConfig({
jshint: {
all: ['Gruntfile.js','lib/**/*.js','test/**/*.js']
}
});
用默认的jshint选项,运行grunt jshint:all 将会检查工程的Gruntfile和lib目录、test目录及其子目录的所有js文件。
Linting before and after concatenating 在连接的前/后检查
下面的例子中,运行grunt jshint 将会检查“beforeconcat”项和“afterconcat”项的文件。dist/output.js可能被检查时还没有被创建出来(通过grunt-contrib-concat插件concat任务)。
这种情况下,你应该先检查“beforecaocat”文件,接着执行concat任务,然后检查“afterconcat”文件靠运行grunt jshint:beforeconcat concat jshint:afterconcat
grunt.initConfig({
concat: {
dist: {
src: ['src/foo.js','src/bar.js'],
dest: 'dist/output.js'
}
},
jshint: {
beforeconcat: ['src/foo.js','src/bar.js'],
afterconcat: ['dist/output.js']
}
});