【问题标题】:Closure Compiler doesn't minify functions inside anonymous function闭包编译器不会缩小匿名函数中的函数
【发布时间】:2017-02-02 02:18:07
【问题描述】:

我有这段从 TypeScript 编译为 JavaScript 的代码,我想用 Google Closure Compiler 对其进行压缩:

var api;
(function (api) {
    function connect() {
        console.log("connected!");
    }
    api.connect = connect;
})(api || (api = {}));
api.connect();

这被编译为:

var a;
(function(b) {
  b.connect = function() {
    console.log("connected!");
  };
})(a || (a = {}));
a.connect();

如您所见,匿名函数中的connect 函数的名称并未重命名为ab 之类的名称。

如何告诉编译器缩小 connect 函数的名称?

编辑:

似乎这是因为connect 是保留字。当我将connect 替换为connectt 时,问题就消失了。

var api;
(function (api) {
    function connectt() {
        console.log("connected!");
    }
    api.connectt = connectt;
})(api || (api = {}));
api.connectt();

编译为:

var a;
(function(b) {
  b.a = function() {
    console.log("connected!");
  };
})(a || (a = {}));
a.a();

感谢@A。安德烈斯!

【问题讨论】:

  • 查看 API 文档我看不到有关您想要什么的选项...但是您总能找到一个在 Goggle Closure Compiler 运行后混淆代码的工具。

标签: javascript google-closure-compiler


【解决方案1】:

某些属性不会被重命名,因为它们是在 externs file 中声明的。如果编译器不能确定一个属性是否是外部依赖的一部分,那么它就不会被重命名。

在您的具体情况下,我可以看到有一个名为 connect 的方法是 externs/browser/w3c_audio.js (AudioNode.prototype.connect) 中 Web 音频 API 的一部分。

Closure Compiler FAQ 和那里提到的博客文章对属性重命名进行了详细说明。

【讨论】:

  • 有没有办法明确告诉编译器重命名connect函数?
【解决方案2】:

问题在于您如何通过 IIFE 参数传入命名空间。如果你避免这种情况,你就会得到你想要的结果。

const api = {};
(function () {
  function connect() {
    console.log("connected!");
  }
  api.connect = connect;
})();
api.connect();

编译器无法将api 识别为一种类型,因此没有足够的信息将属性与其他对象区分开来。通过避免由 IIFE 调用创建的别名并使用 const 告诉编译器 api 是一个命名空间,您可以获得所需的优化。

【讨论】:

  • 我无法避免通过 IIFE 参数传入命名空间,因为 TypeScript 会生成此构造。
  • 不幸的是,编译器没有其他方法可以重命名这些属性。它没有足够的信息表明这种重命名是安全的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-14
  • 1970-01-01
  • 2017-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-08
相关资源
最近更新 更多