【问题标题】:Closure compiler export Typescript classes and functions闭包编译器导出 Typescript 类和函数
【发布时间】:2015-07-08 18:27:53
【问题描述】:

我正在尝试在 typescript 生成的类上使用闭包编译器高级模式,但没有成功。有没有人做过这样的事情。

打字稿类

class TestData {
BlogName: string;
CacheTimeOut: number;
CopyrightHolder: string;

constructor(blogName: string, cacheTimeOut: number, copyrightHolder: string) {
    this.BlogName = blogName;
    this.CacheTimeOut = cacheTimeOut;
    this.CopyrightHolder = copyrightHolder;
}

addBlog(value: string): boolean {
    console.log('add blog');
    return true;
}

validate(): boolean {
    console.log('all valid');
    return true
}       
}

var myTestData = new TestData("name",22,"cpyright");

生成的代码

var TestData = (function () {
function TestData(blogName, cacheTimeOut, copyrightHolder) {
    this.BlogName = blogName;
    this.CacheTimeOut = cacheTimeOut;
    this.CopyrightHolder = copyrightHolder;
}
TestData.prototype.addBlog = function (value) {
    console.log('add blog');
    return true;
};
TestData.prototype.validate = function () {
    console.log('all valid');
    return true;
};
return TestData;

})();var myTestData = new TestData();

这编译成

new function() {};

我知道我应该提供出口,所以我添加了

window['TestData'] = TestData;
window['TestData'].prototype['addBlog'] = TestData.prototype.addBlog
window['TestData'].prototype['validate'] = TestData.prototype.validate

我的闭包编译器高级编译的输出是

var a = function() {
  function b() {
  }
  b.prototype.a = function() {
    console.log("add blog");
    return !0;
  };
  b.prototype.b = function() {
    console.log("all valid");
    return !0;
  };
  return b;
}();
window.TestData = a;
window.TestData.prototype.addBlog = a.prototype.a;
window.TestData.prototype.validate = a.prototype.b;
new a;

如果您看到仍然没有剩下的构造函数代码。当我们在模块中添加它时,情况会变得更糟。

我也尝试使用谷歌关闭的@export,但没有成功

我看到几个插件可以生成基于 typescript 的闭包编译器注释,但它们也不会生成正确的代码。

Thirdparty closure annotations generator

【问题讨论】:

  • 闭包编译器移除死代码。您可以使用 goog.provide 导出此类并使用 goog.require 来使用它。但是如果你不在任何代码中使用它,它就不会显示在编译的代码中
  • 所以应该手动给生成的代码..?
  • 我试过 goog.provide('TestData');还是不行
  • @anandaravindan 它在高级模式下被删除,因为您从不使用这些属性。如果这是“你所有的代码”,那么它正在正确地优化它——因为你永远不需要这些值。如果这是“您的一些代码”,您需要更加保守,并使用简单的优化来避免丢失可能在其他地方使用的内容。
  • @史蒂夫芬顿。明白了。我在方法博客中使用了这些变量并且它起作用了。谢谢。

标签: javascript typescript minify google-closure-compiler bundling-and-minification


【解决方案1】:

我对此进行了非常基本的测试。也许您更改了代码并且没有重新尝试。

如果您在问题中编译 TypeScript,它应该会生成以下 JavaScript:

var TestData = (function () {
    function TestData(blogName, cacheTimeOut, copyrightHolder) {
        this.BlogName = blogName;
        this.CacheTimeOut = cacheTimeOut;
        this.CopyrightHolder = copyrightHolder;
    }
    TestData.prototype.addBlog = function (value) {
        console.log('add blog');
        return true;
    };
    TestData.prototype.validate = function () {
        console.log('all valid');
        return true;
    };
    return TestData;
})();
var myTestData = new TestData("name", 22, "cpyright");

特别是,最后一行将参数传递给TestData 构造函数。

使用@compilation_level SIMPLE_OPTIMIZATIONS 快速运行此结果(空白是我的):

var TestData=function(){
    function a(a,b,c){
        this.BlogName=a;this.CacheTimeOut=b;this.CopyrightHolder=c
    }
    a.prototype.addBlog=function(a){console.log("add blog");return!0};
    a.prototype.validate=function(){
        console.log("all valid");return!0
    };
    return a
}(),myTestData=new TestData("name",22,"cpyright");

如果你对部分代码使用高级优化,它会过于激进。您需要为 Closure 编译器提供所有代码,以了解真正没有使用的代码。

如果您的示例代表您的所有代码,您会注意到构造函数以及所有三个属性(BlogName、CacheTimeOut 和 CopyrightHolder)实际上从未使用过,因此可以在不影响程序行为的情况下将其删除。

【讨论】:

  • 我说的是高级编译。不是空白。
  • 上面的例子是简单的优化(不是空白)。要使高级编译成为您的一个选项 - 您需要将所有代码提供给编译器。它删除了未使用的代码,因此它需要了解所有代码才能正确理解所使用的代码。例如,如果您添加一个控制台日志语句来显示myTestData.BlogName 的值,突然该参数不会被删除,因为它被使用了...var b=new function(a){this.a=a}("name",22,"cpyright");console.log(b.a);
【解决方案2】:

答案:优化的 noops 是 - 等待它 - noops :)

解释:

如果您在此处使用您的 gen 代码 http://www.closure-compiler.appspot.com/home 使用 ADVANCED_OPTIMIZATIONS 它产生:

new function(){};

如果你添加 myTestData.addBlog("test"); 它会产生:

(new (function(){function a(){}a.prototype.a=function(){console.log("add blog")};return a}())).a();

【讨论】:

  • 我知道了。但是为什么构造函数里没有代码
  • @anandaravindan 因为编译器可以告诉你永远不要使用这些值 - 所以你不需要在构造函数中接受它们,或者存储它们。
  • 因为没有代码可以做任何事情,你说的but why there is no code in the constructor是什么意思。据我了解,没有外部变量,编译器将您的代码视为“仅此而已”,并且由于您从不使用 var,因此它会丢弃构造函数,然后丢弃整个“类型”,因为不需要它,直到“什么都没有。
  • 无论如何我可以自动化这个窗口['TestData'] = TestData; window['TestData'].prototype['addBlog'] = TestData.prototype.addBlog window['TestData'].prototype['validate'] = TestData.prototype.validate 我想我可以使用@export 注释。但它没有用。我也添加了所需的 base.js。
  • @anandaravindan,我不明白,你的总体目标是什么?
猜你喜欢
  • 1970-01-01
  • 2021-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多