Javascript Typescript和Google闭包

Javascript Typescript和Google闭包,javascript,obfuscation,typescript,google-closure-compiler,Javascript,Obfuscation,Typescript,Google Closure Compiler,我使用Typescript命令(tsc)创建一个包含所有平台类的Javascript文件 tsc "./Main.ts" -out "./script/myProject_debug.js" --declarations 然后,我想用Google闭包(compiler.jar)混淆这个文件,如下所示: java -jar ./compiler/compiler.jar --compilation_level ADVANCED_OPTIMIZATIONS --js "./script/myPro

我使用Typescript命令(tsc)创建一个包含所有平台类的Javascript文件

tsc "./Main.ts" -out "./script/myProject_debug.js" --declarations
然后,我想用Google闭包(compiler.jar)混淆这个文件,如下所示:

java -jar ./compiler/compiler.jar --compilation_level ADVANCED_OPTIMIZATIONS --js "./script/myProject_debug.js" > "./script/myProject.js".
但是当我执行结果模糊/优化代码时,我得到了以下错误:uncaughttypeerror:无法读取未定义的属性“prototype”

与以下非模糊JS代码(由tsc命令生成)匹配:

此部分用于翻译“extends”Typescript关键字,而b的等价项未定义

是否有人遇到了类似的错误或/或得到了一个解决方案,能够用Typescript编译的文件混淆googleclosure

我尝试使用uglifyjs命令,输出文件工作得很好,但我希望完全混淆(类、参数、变量、方法等)。此外,谷歌闭包提供的额外优化也将受到欢迎


谢谢你

扩展的
定义有一个问题,很可能导致您看到的错误

var __extends = this.__extends || function (d, b) { ... };
this.\uuu extends
引用与
窗口是一样的。\uu extends
,但是闭包编译器不知道(甚至尝试)在全局上下文中对
this
的引用实际上是
窗口
对象。使用
--warning\u level=VERBOSE编译时,编译器将发出警告:

Dangerous use of the global this object at line 1 character 16
var __extends = this.__extends || function (d, b) {
                ^
此外,
this.\uu extends
是对外部/未定义属性的引用,编译器还在
VERBOSE
级别发出警告

我已经修改并注释了定义,以便在没有警告的情况下使用:


好的,我找到问题了

如前所述,b在以下情况中未定义:

var __extends = this.__extends || function (d, b) {
   function __() { this.constructor = d; }
   __.prototype = b.prototype;
   d.prototype = new __();
}
当typescript“编译”成javascript时,如果您每个项目都有一个名称空间,但您将与此名称空间相关的所有类都写入单独的文件中,那么typescript将在最终生成的js文件中执行以下操作:

var namespace;
(function (namespace) {

    var Class1 = (function (dependency) {
        [...]
        return Class1;
    })(namespace.dependency);

    namespace.Class1 = Class1;
})(namespace || (namespace= {}));

var namespace;
(function (namespace) {

    var Class2 = (function (dependency) {
        [...]
        return Class2;
    })(namespace.dependency);

    namespace.Class2 = Class2;
})(namespace || (namespace= {}));

var namespace;
(function (namespace) {

    var Main = (function (dependency) {
        [...]
        return Main;
    })(namespace.Class2);

    namespace.Main = Main;
})(namespace || (namespace= {}));
我不知道它到底是如何工作的,但是google closure编译器在某个地方删除了一些类,即使这些代码没有问题,JS也可以处理。因此,缺少一些依赖项,而b未定义

因此我发现,如果您像下面这样声明名称空间,您将不会再遇到错误(只要使用“Main”类,closure将在最终的模糊js文件中保留所有类,或者在全局窗口对象中保留名称空间的引用):

我想我会在typescriptlang.org上发表一篇文章。顺便说一下,它正在优化生成的文件大小


谢谢你的回答

闭包编译器和UglifyJS都不会混淆javascript。两者都缩小了它,是的,这使它更难阅读-但它仍然是相同的脚本。如果您通过美化器运行输出,您将获得原始脚本-尽管它将被删除注释并具有不同的变量名。@AHM闭包编译器不是这样的。它是一个真正的优化编译器,可以以非平凡的方式更改代码。在许多情况下,美化代码并不会使您获得任何接近原始脚本的东西。是的,这是真的,但即使启用了高级优化,代码也不会变得模糊。任何对javascript有很好理解的人都能够理解代码在做什么。如果目标是最小化和优化代码闭包是一个很好的工具,但是如果目标是混淆它,我认为它不是很有用。你知道实现它的另一个好方法吗?我更喜欢面向命令行的解决方案(如果可能的话,我不想每次构建时都打开一个软件或类似的东西)。但是闭包编译器似乎更善于混淆代码。YuiCompressor的输出类似于UglifyJS生成的输出。还有另一个问题,但这个答案有助于找到答案。谢谢
var __extends = this.__extends || function (d, b) {
   function __() { this.constructor = d; }
   __.prototype = b.prototype;
   d.prototype = new __();
}
var namespace;
(function (namespace) {

    var Class1 = (function (dependency) {
        [...]
        return Class1;
    })(namespace.dependency);

    namespace.Class1 = Class1;
})(namespace || (namespace= {}));

var namespace;
(function (namespace) {

    var Class2 = (function (dependency) {
        [...]
        return Class2;
    })(namespace.dependency);

    namespace.Class2 = Class2;
})(namespace || (namespace= {}));

var namespace;
(function (namespace) {

    var Main = (function (dependency) {
        [...]
        return Main;
    })(namespace.Class2);

    namespace.Main = Main;
})(namespace || (namespace= {}));
var namespace;
(function (namespace) {

    var Class1 = (function (dependency) {
        [...]
        return Class1;
    })(namespace.dependency);

    namespace.Class1= Class1;

    var Class2 = (function (dependency) {
        [...]
        return Class2;
    })(namespace.dependency);

    namespace.Class2= Class2;

    var Main = (function (dependency) {
        [...]
        return Main;
    })(namespace.Class2);

    namespace.Main = Main;
})(namespace || (namespace= {}));