【问题标题】:How to minify a single module如何缩小单个模块
【发布时间】:2014-03-04 18:20:23
【问题描述】:

我正在尝试为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(){})();,这似乎有点杂乱无章。

或者是否有另一个缩小器(它不必在线)可以正确处理这个问题?

【问题讨论】:

  • uglifyjs?这是工作的标准工具......
  • 您可以在lisperator.net/uglifyjs/#demo 尝试它 - 但我找不到执行上述操作的方法。命令行中有特定的开关吗?
  • 等等……“折叠”是什么意思?你想混淆像doStuff这样的局部变量吗?
  • 不混淆,但在适当的地方'内联'。例如,在我的示例中,C.CONST1 被其实际值替换,doStuff 被内联,加法被拉入三元运算符。

标签: javascript node.js minify


【解决方案1】:

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

至于折叠,我相信在 javascript 中通常是不可能的。在您的特定情况下,它会起作用,但一般代码通常过于复杂,静态分析器无法执行此类操作。

【讨论】:

  • 谢谢...看起来 uglifyjs 不做折叠。闭包编译器足够聪明地做到这一点 - 可惜似乎没有一种简单的方法来启用该功能。
  • 只是补充一点,虽然我知道它不能一直做到,但在我使用它的 99% 的情况下,它是一个巨大的帮助。
【解决方案2】:

好吧,看起来唯一的解决方案就是按照我最初在问题中提到的那样做,不管它有多少杂乱无章:

将代码包装在:

(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}}

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

【讨论】:

    猜你喜欢
    • 2020-01-19
    • 2023-03-23
    • 1970-01-01
    • 2017-08-23
    • 1970-01-01
    • 2021-12-04
    • 2016-08-20
    • 1970-01-01
    • 2016-03-14
    相关资源
    最近更新 更多