API参考

假如是通过NPM安装的,你可以这样在你的应用中加载UglifyJS:

  1. var UglifyJS = require("uglify-js");

它会输出很多模块,但我在此只介绍一下涉及解释、混淆和压缩的基础代码。按(1)
解释, (2) 压缩, (3) 混淆, (4) 生成输出代码的顺序。

简易使用模式

minify是一个顶级的、单独、包含所有步骤的方法。如果你不需要进一步自定义的话,你应该会喜欢使用它。

例子:

  1. var result = UglifyJS.minify("/path/to/file.js");
  2. console.log(result.code); // 最小化输出
  3. // 假如你不想传一个文件名,而是要传入一段代码
  4. var result = UglifyJS.minify("var b = function () {};", {fromString: true});

你也可以压缩多个文件:

  1. var result = UglifyJS.minify([ "file1.js", "file2.js", "file3.js" ]);
  2. console.log(result.code);

这样生成一份sourcemap:

  1. var result = UglifyJS.minify([ "file1.js", "file2.js", "file3.js" ], {
  2. outSourceMap: "out.js.map"
  3. });
  4. console.log(result.code); // 最小化输出
  5. console.log(result.map);

你也可以用一个带fromString选项的对象来要生成sourcemap:

  1. var result = UglifyJS.minify({"file1.js": "var a = function () {};"}, {
  2. outSourceMap: "out.js.map",
  3. outFileName: "out.js",
  4. fromString: true
  5. });

要注意,此时sourcemap并不会保存为一份文件,它只会返回在result.map中。outSourceMap 的值只用来在result.code中设置//# sourceMappingURL=out.js.mapoutFileName 的值只用来在sourcemap文件中设置 file属性。

sourcemap(查阅规格)中的file属性会优先使用 outFileName ,假如没有,会从outSourceMap中推导(就是去掉'.map')。

你可以把sourceMapInline设为true ,这样sourcemap会加在代码末尾。

你也可以指定sourcemap中的源文件根目录(sourceRoot)属性:

  1. var result = UglifyJS.minify([ "file1.js", "file2.js", "file3.js" ], {
  2. outSourceMap: "out.js.map",
  3. sourceRoot: "http://example.com/src"
  4. });

如果你要压缩从其他文件编译得来的带一份sourcemap的JS文件,你可以用inSourceMap参数:

  1. var result = UglifyJS.minify("compiled.js", {
  2. inSourceMap: "compiled.js.map",
  3. outSourceMap: "minified.js.map"
  4. });
  5. // 跟之前一样,返回 `code`和 `map`

如果你要输入的sourcemap并非一份单独文件,你可以在对象参数中设置inSourceMap参数:

  1. var result = UglifyJS.minify("compiled.js", {
  2. inSourceMap: JSON.parse(my_source_map_string),
  3. outSourceMap: "minified.js.map"
  4. });

只有在需要outSourceMap时, inSourceMap 才会被用到(否则就没用咯)。

要设置sourcemap的url的话,请用 sourceMapUrl选项。

如果你要用X-SourceMap请求头,你可以把sourceMapUrl选项设为false。
outSourceMap的默认设置:

  1. var result = UglifyJS.minify([ "file1.js" ], {
  2. outSourceMap: "out.js.map",
  3. sourceMapUrl: "localhost/out.js.map"
  4. });

其他选项:

  • warnings (默认 false) — 传true来现实压缩器的警告

  • fromString (默认 false) — 传true的话,你可以输入JS源码,而不是文件名。

  • mangle (默认 true) — 传false来跳过混淆步骤,或者传一个对象来特定指明混淆选项(下面详述)。

  • mangleProperties (默认 false) — 传一个对象来自定义指明混淆对象属性的选项。

  • output (默认 null) — 如果你要进一步指定输出选项,请传一个对象。默认是压缩到最优化。

  • compress (默认 {}) — 传false的话就跳过整个压缩步骤。自定义的话请传一个压缩选项对象。

  • parse (默认 {}) — 如果你要进一步自定义解释步骤请传一个解释选项对象(不是所有选项都有效….下面再说)。

混淆

  • except - 传一个应该排除在混淆之外的标识的数组。

    • toplevel — 混淆那些定义在顶层作用域的名字(默认禁用)。

    • eval — 混淆那些在with或eval中出现的名字(默认禁用)。

    • keep_fnames — 默认false。传true的话就不混淆函数名。对那些依赖Function.prototype.name的代码有用。延展阅读:keep_fnames 压缩选项.

例子:

  1. //tst.js
  2. var globalVar;
  3. function funcName(firstLongName, anotherLongName)
  4. {
  5. var myVariable = firstLongName + anotherLongName;
  6. }
  7. UglifyJS.minify("tst.js").code;
  8. // 'function funcName(a,n){}var globalVar;'
  9. UglifyJS.minify("tst.js", { mangle: { except: ['firstLongName'] } }).code;
  10. // 'function funcName(firstLongName,a){}var globalVar;'
  11. UglifyJS.minify("tst.js", { mangle: { toplevel: true } }).code;
  12. // 'function n(n,a){}var a;'

混淆属性名选项

  • regex — 传一个正则,仅混淆匹配到的名字。(与--mangle-regex CLI参数选项关联)
  • ignore_quoted – 只混淆非括号中的属性名(与--mangle-props 2 CLI 参数选项关联)

  • debug – 让混淆后的名字与原名字有关。与--mangle-props-debug CLI 参数选项关联)。默认是false。传一个空字符串来启用,或者传一个非空字符串来添加后缀。

高级使用模式

如果minify函数太简单不能满足你的需求,下面这些API信息有更多的细节详情:

解释器

  1. var toplevel_ast = UglifyJS.parse(code, options);

options 是可选的,要传的话就必须传个对象。下面这些是有效的属性:

  • strict — 禁用自动添加分号,禁止数组、对象末尾还有逗号。
  • bare_returns — 允许函数返回外部。(与 --bare-returns CLI参数选项关联,对minify parse选项对象也有效。)
  • filename — 输入的文件名。
  • toplevel — 一个 toplevel 节点。 (就是之前调用parse返回的)

后面两个选项是当你要最小化多个文件成一个文件(以及正确的sourcemap)时有用。我们的CLI会像这样处理:

  1. var toplevel = null;
  2. files.forEach(function(file){
  3. var code = fs.readFileSync(file, "utf8");
  4. toplevel = UglifyJS.parse(code, {
  5. filename: file,
  6. toplevel: toplevel
  7. });
  8. });

完成后,我们就在toplevel这个大AST里包含了我们的所有文件,每一份都带着正确的来源信息。

作用域信息

UglifyJS包含一个作用域分析器,你可以在压缩、混淆前手动调用。基本上,它添加了AST中的节点在哪里被命名、被引用了多少次、是否全局的、是否在evalwith中声明等等。我们将讨论除此之外的,那些在你对AST进行任何操作前必须知道的重要事项:

  1. toplevel.figure_out_scope()

压缩

就如这样:

  1. var compressor = UglifyJS.Compressor(options);
  2. var compressed_ast = compressor.compress(toplevel);

options可以不要。之前的“压缩器选项“中已经讲过可以填什么。默认选项对大多数脚本来说应该都是最佳的。

压缩器是破坏性的,所以不要依赖那些源树toplevel

混淆

压缩之后再调用一次figure_out_scope是个好做法(因为压缩过程可能会干掉一些没用的、不可达的代码,改变标识的数量和位置),你也可以选择在Gzip(统计不可混淆的词中字符的使用频率)后调用。例如:

  1. compressed_ast.figure_out_scope();
  2. compressed_ast.compute_char_frequency();
  3. compressed_ast.mangle_names();

生成输出代码

AST节点带一个print方法,用来生成输出流。基本上,要生成代码你只要这么做:

  1. var stream = UglifyJS.OutputStream(options);
  2. compressed_ast.print(stream);
  3. var code = stream.toString(); // 这就是你最小化后的代码

又或者这样缩写:

  1. var code = compressed_ast.print_to_string(options);

通常情况下options是可选的。输出流可以接收一堆选项参数,绝大多数在”美化选项“中有阐述。我们所关心的是source_mapcomments选项。

在输出代码中保留注释

你需要传入comments选项来保留某些注释。你可以传正则表达式(以/包裹或正则对象)、布尔值或函数。也可以传字符串allsomesome等同于CLI中--comments不带任何参数。如果你传正则,只有匹配到的注释会被保留。注意,匹配的主体不包括 ///*。如果你传函数,每遇到树中的注释都会调用一下,传入两个参数,一是注释所依附的节点,二是注释标识本身。

注释标识有如下属性:

  • type: 单行注释是”comment1”,多行注释 “comment2”。
  • value: 注释体本身。
  • posendpos: 注释在源码中出现的起始位置/结束位置(从0开始索引)。
  • linecol: 注释在源码中出现的行和列。
  • file — 源码的文件名
  • nlb — 在源码中,如果注释前有一空行或注释另起新一行的话是true

你的函数返回true的话就保留注释,其他返回值都代表false。

生成sourcemap

你需要在调用print时传source_map参数。source_map参数需要是SourceMap对象(在source-map库顶部有个小框框里说了)。

例子:

  1. var source_map = UglifyJS.SourceMap(source_map_options);
  2. var stream = UglifyJS.OutputStream({
  3. ...
  4. source_map: source_map
  5. });
  6. compressed_ast.print(stream);
  7. var code = stream.toString();
  8. var map = source_map.toString(); // 输出json格式sourcemap

source_map_options(可选)包含以下属性:

  • file: 被输出的、sourcemap所映射的JS的文件名
  • root: sourceRoot 属性 (详看 规格)
  • orig: “original source map”,方便你想让sourcemap映射到生成JS的源码上。此参数可以只是字符串或json,也可以是包含源码sourcemap的json对象。

兼容版

Harmony

如果你想使用能最小化ES6+的实验性质的兼容分支,请在你的package.json 文件中加上下面代码:

  1. "uglify-js": "git+https://github.com/mishoo/UglifyJS2.git#harmony"

或者直接安装兼容实验版UglifyJS:

  1. npm install --save-dev uglify-js@github:mishoo/UglifyJS2#harmony

更多细节请看 #448