如何缩小单个模块

时间:2014-02-27 12:53:37

标签: javascript node.js minify

我正在尝试为Espruino(运行JavaScript的微控制器)缩小node.js样式模块。这些模块通常会定义隐藏的内部常量和便利函数,我想将它们折叠起来。

作为一个非常人为的例子,让我说我有:

var C = {
CONST1 : 32,
CONST2 : 64
};

function Foo() {
}

Foo.prototype.C = {
  ONE : 1,
  TWO : 2
};

function doStuff(x) { 
  return x+1;
}

Foo.prototype.getConst = function (x) {
  return doStuff((x==this.C.ONE) ? C.CONST1 : C.CONST2);
}

exports.foo = function() { return new Foo(); };

我想将其缩小为:

function Foo(){}Foo.prototype.C={ONE:1,TWO:2};Foo.prototype.getConst=function(a){return a==this.C.ONE?33:65};exports.foo=function(){return new Foo};

然而,目前我正在使用闭包编译器在线服务,这将在“简单”模式下进行简单的缩小(不在隐藏的CdoStuff中折叠):

var C={CONST1:32,CONST2:64};function Foo(){}Foo.prototype.C={ONE:1,TWO:2};function doStuff(a){return a+1}Foo.prototype.getConst=function(a){return doStuff(a==this.C.ONE?C.CONST1:C.CONST2)};exports.foo=function(){return new Foo};

或'高级'它会发疯,重命名函数并删除所有内容:

function a(){}exports.a=function(){return new a};

那么我如何告诉它保留exports的所有孩子以及这些孩子所引用的所有内容(名称相同)?

将代码包装在:

(function(){
  ...
})();

具有预期的效果,但是我必须从返回的内容中删除(function(){})();,这看起来有点像污泥。

还是有另一个缩小器(它不必在线)可以正确处理吗?

2 个答案:

答案 0 :(得分:1)

您可以使用uglifyjs -m toplevel缩小本地名称。

至于折叠,我相信它通常不可能在javascript中。在你的特殊情况下它会起作用,但是一般代码通常太复杂,静态分析器不能做那样的技巧。

答案 1 :(得分:0)

嗯,看起来唯一的解决办法就像我最初在问题中提到的那样,不管它有多大的污点:

将代码包装在:

(function(){
  ...
})();

使用SIMPLE_OPTIMIZATIONS将其传递给闭包编译器,然后从响应的开头和结尾删除(function(){})();

这允许闭包编译器进行常量折叠,在很多情况下完全删除C数组,并真正减少代码大小。

因此,使用上面的示例,而不是:

var C={CONST1:32,CONST2:64};function Foo(){}Foo.prototype.C={ONE:1,TWO:2};function doStuff(a){return a+1}Foo.prototype.getConst=function(a){return doStuff(a==this.C.ONE?C.CONST1:C.CONST2)};exports.foo=function(){return new Foo};

我明白了:

function a(){}a.prototype.C={ONE:1,TWO:2};a.prototype.getConst=function(a){return(a==this.C.ONE?32:64)+1};exports.foo=function(){return new a}}

这不仅可以节省代码大小,还可以节省执行该代码所需的内存。