我正在尝试为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};
然而,目前我正在使用闭包编译器在线服务,这将在“简单”模式下进行简单的缩小(不在隐藏的C
和doStuff
中折叠):
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(){
和})();
,这看起来有点像污泥。
还是有另一个缩小器(它不必在线)可以正确处理吗?
答案 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}}
这不仅可以节省代码大小,还可以节省执行该代码所需的内存。