├── .gitignore ├── README.md ├── index.js ├── package.json └── test ├── digofile.js ├── fixtures ├── basic.js └── error.js └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | _build -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # digo-uglify-js 2 | [digo](https://github.com/digojs/digo) 插件:使用 [UglifyJS](https://github.com/mishoo/UglifyJS) 混淆、压缩或格式化 JS。 3 | 4 | ## 安装 5 | ```bash 6 | npm install digo-uglify-js -g 7 | ``` 8 | 9 | ## 使用 10 | ### 压缩 JS 11 | ```js 12 | digo.src("*.js", "!*.min.js").pipe("digo-uglify-js"); 13 | ``` 14 | 15 | ### JS 语法检查 16 | ```js 17 | digo.src("*.js").pipe("digo-uglify-js", { 18 | compress: false 19 | }); 20 | ``` 21 | 22 | ### 格式化 JS 23 | ```js 24 | digo.src("*.js").pipe("digo-uglify-js", { 25 | compress: false, 26 | output: { 27 | beautify: true 28 | } 29 | }); 30 | ``` 31 | 32 | ### 源映射(Source Map) 33 | 本插件支持生成源映射,详见 [源映射](https://github.com/digojs/digo/wiki/源映射)。 34 | 35 | ## 用法 36 | ```js 37 | digo.src("*.js").pipe("digo-uglify-js", { 38 | warnings: false, // 是否输出警告(如删除无用代码时会产生警告)。 39 | parse: { 40 | strict: false, // 是否启用 JS 严格模式。 41 | toplevel: null, // 顶层语法树节点。 42 | filename: null, // 源文件名,主要用于报错。* 43 | }, 44 | mangle: { // 是否混淆变量名。true 表示全部混淆;false 表示全部不混淆。 45 | except: null, // 禁止混淆的变量名数组。如 ['$']。 46 | keep_fnames: false, // 是否保留函数名。如果设为 false,可能会导致依赖 Function.prototype.name 的代码出错。 47 | toplevel: false, // 是否混淆全局变量名。 48 | eval: false, // 是否混淆 eval 和 with 可能用到的变量名。 49 | }, 50 | mangleProperties: false/* { // 是否混淆属性名。true 表示全部混淆;false 表示全部不混淆。 51 | regex: null, // 正则表达式。如果匹配属性名则混淆。 52 | ignore_quoted: false, // 是否忽略引号形式的属性调用。 53 | }*/, 54 | compress: { // 是否压缩代码。false 表示全部不压缩。 55 | drop_console: true, // 是否删除 console.log 等调用。* 56 | drop_debugger: true, // 是否删除 debugger 语句。* 57 | dead_code: true, // 是否删除永远无法执行的代码。如 if(false) { }。* 58 | global_defs: { // 预设全局常量。* 59 | DEBUG: false, 60 | RELEASE: true 61 | }, 62 | unsafe: false, // 是否允许不安全的深度压缩。如 new Object() → {}。详见 https://github.com/mishoo/UglifyJS2#the-unsafe-option。 63 | sequences: true, // 是否将连续语句转为逗号表达式。如 a = 1; return b; → return a=1, b; 。 64 | properties: true, // 是否将常量属性名转为调用表达式。如 a["foo"] → a.foo。 65 | comparisons: true, // 是否优化比较运算。如 !(a <= b) → a > b (仅当 unsafe 为 true 时优化)和 a = !b && !c && !d && !e → a=!(b||c||d||e)。 66 | unsafe_comps: false, // 是否将 < 和 <= 分别转为 > 和 >= 来改进比较性能。设为 true 可能导致对象比较时出错。仅当 comparisons 为 true 时生效。 67 | conditionals: true, // 是否优化常量条件表达式,如 true ? a : b。 68 | evaluate: true, // 是否尝试执行常量表达式。详见 https://github.com/mishoo/UglifyJS2#conditional-compilation。 69 | booleans: true, // 是否优化布尔运算。如 !!a ? b : c → a ? b : c。 70 | loops: true, // 是否优化常量循环。如 while(true) → while(1) 71 | unused: true, // 是否删除未引用的局部变量和函数。 72 | hoist_funs: true, // 是否置顶函数声明。 73 | hoist_vars: false, // 是否置顶变量声明。如果为 true 可能导致代码量增加。 74 | if_return: true, // 是否优化 return/continue 语句后的 if 语句。 75 | join_vars: true, // 是否合并多个 var 语句。 76 | cascade: true, // 是否尝试简化逗号表达式。如 x = something(), x → x = something()。 77 | collapse_vars: false, // 是否内联只用到一次的变量和常量。 78 | reduce_vars: false, // 是否内联只赋值一次(类似常量)的变量。 79 | warnings: false, // 是否压缩删除代码时是否输出警告。 80 | negate_iife: false, // 是否将未使用返回值的立即执行的函数表达式改为 ! 表达式。如 (function(){})() → !function(){}()。 81 | pure_getters: false, // 是否将所有属性和字段都作为无副作用的调用处理。 82 | pure_funcs: null, // 无副作用的函数全称数组。如 ["Math.floor"], 83 | side_effects: true, // 是否删除无副作用的函数调用。如 console.log() 删除后不会影响其它逻辑。 84 | keep_fargs: true, // 是否保留未使用的函数参数。如果设为 false,可能会导致依赖 Function.prototype.length 的代码出错。 85 | keep_fnames: false, // 是否保留函数名。如果设为 false,可能会导致依赖 Function.prototype.name 的代码出错。 86 | screw_ie8: false, // 是否删除 IE8 兼容代码。 87 | passes: 1, // 执行压缩的次数。 88 | }, 89 | output: { 90 | beautify: false, // 是否格式化代码。 91 | indent_level: 4, // 缩进空格数。仅当 beautify 为 true 时有效。 92 | indent_start: 0, // 首行的缩进空格数。仅当 beautify 为 true 时有效。 93 | width: 80, // 允许最大列数。仅当 beautify 为 true 时有效。 94 | quote_keys: false, // 是否使用引号定义 JSON 对象的键。 95 | quote_style: 0, // 引号风格。0:优先使用双引号。1:全部使用单引号。2:全部使用双引号。3:保留原引号。 96 | keep_quoted_props: false, // 是否保留对象字面量中的引号。 97 | space_colon: true, // 是否在冒号后添加一个空格。 98 | ascii_only: false, // 是否编码特殊 Unicode 字符。 99 | inline_script: false, // 是否编码 " *: 插件内部已设置了此选项的默认值。 115 | 116 | 另参考: [https://github.com/mishoo/UglifyJS2](https://github.com/mishoo/UglifyJS2)。 117 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var uglifyJS = require("uglify-js"); 2 | 3 | module.exports = function UglifyJS(file, options) { 4 | 5 | // 设置默认选项。 6 | options = merge(options, { 7 | sourceMap: file.sourceMap ? { 8 | content: file.sourceMapObject 9 | } : false, 10 | ie8: true, 11 | parse: { 12 | filename: file.srcPath 13 | }, 14 | compress: { 15 | drop_console: true, 16 | dead_code: true, 17 | drop_debugger: true, 18 | global_defs: { 19 | DEBUG: false, 20 | RELEASE: true 21 | } 22 | }, 23 | output: { 24 | comments: /^!|@preserve|@license|@cc_on/ 25 | } 26 | }); 27 | 28 | // 生成。 29 | var result = uglifyJS.minify(file.content, options); 30 | if (result.error) { 31 | return file.error({ 32 | plugin: UglifyJS.name, 33 | message: result.error.message, 34 | line: result.error.line == undefined ? undefined : result.error.line - 1, 35 | column: result.error.col, 36 | error: result.error, 37 | }); 38 | } 39 | if (result.warnings && result.warnings.length) { 40 | for (var i = 0; i < result.warnings.length; i++) { 41 | var warning = result.warnings[i]; 42 | var match = /\s*\[\d+:(\d+),(\d+)\]$/.exec(warning); 43 | file.warning({ 44 | plugin: UglifyJS.name, 45 | message: match ? warning.substr(0, match.index) : warning, 46 | line: match && +match[1], 47 | column: match && +match[2] 48 | }); 49 | } 50 | } 51 | 52 | // 保存。 53 | file.content = result.code; 54 | if (result.map) { 55 | var map = JSON.parse(result.map); 56 | map.sources[0] = file.srcPath; 57 | file.sourceMapObject = map; 58 | } 59 | }; 60 | 61 | function merge(src, dest) { 62 | for (var key in src) { 63 | if (src[key] && dest[key] && typeof src[key] === "object" && typeof dest[key] === "object") { 64 | merge(dest[key], src[key]); 65 | } else { 66 | dest[key] = src[key]; 67 | } 68 | } 69 | return dest; 70 | } 71 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "digo-uglify-js", 3 | "version": "0.1.1", 4 | "repository": "http://github.com/digojs/digo-uglify-js", 5 | "description": "digo 插件:使用 UglifyJS 混淆、压缩或格式化 JS", 6 | "keywords": [ 7 | "digo plugin", 8 | "mangle js", 9 | "minify js", 10 | "compress js", 11 | "format js", 12 | "beautify js" 13 | ], 14 | "license": "MIT", 15 | "author": "xuld ", 16 | "dependencies": { 17 | "uglify-js": "latest" 18 | }, 19 | "files": [ 20 | "index.js" 21 | ] 22 | } -------------------------------------------------------------------------------- /test/digofile.js: -------------------------------------------------------------------------------- 1 | var digo = require("digo"); 2 | 3 | exports.default = function () { 4 | digo.src("fixtures/*.js").pipe("../").dest("_build"); 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/basic.js: -------------------------------------------------------------------------------- 1 | function a(c) { 2 | var b = undefined; 3 | return b; 4 | } 5 | var c = /*@cc_on!@*/false 6 | 7 | // dasdasdasd 8 | 9 | /*@cc_on alert(0) @*/ 10 | 11 | /*! asdas*/ 12 | if (DEBUG) { 13 | console.log("debug stuff"); 14 | } -------------------------------------------------------------------------------- /test/fixtures/error.js: -------------------------------------------------------------------------------- 1 | var a = 1 2 | var b = ; 3 | function a(c) { 4 | var b = undefined; 5 | return b; 6 | } 7 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | var digo = require("digo"); 3 | var plugin = require(".."); 4 | 5 | describe('digo-uglifyJs', function () { 6 | 7 | it("compress", function () { 8 | assert.equal(exec("var a = 1;"), "var a=1;"); 9 | assert.equal(exec("if (RELEASE) { alert('hello') }"), "alert(\"hello\");"); 10 | assert.equal(exec("if (DEBUG) { alert('hello') }"), ""); 11 | assert.equal(exec("console.log('debug stuff');"), ""); 12 | assert.equal(exec("var c = /*@cc_on!@*/false"), "var c=/*@cc_on!@*/!1;"); 13 | }); 14 | 15 | it("error", function () { 16 | var error = false; 17 | digo.on("log", function (data) { 18 | error = true; 19 | assert.equal(data.line, 0); 20 | assert.equal(data.column, 8); 21 | return false; 22 | }); 23 | assert.equal(exec("var b = ;"), "var b = ;"); 24 | assert.equal(error, true); 25 | digo.off("log"); 26 | }); 27 | 28 | function exec(input, options) { 29 | var file = new digo.File(); 30 | file.content = input; 31 | plugin(file, options); 32 | return file.content; 33 | } 34 | }); 35 | --------------------------------------------------------------------------------