4

Typescript コマンド (tsc) を使用して、すべてのプラットフォーム クラスを含む単一の Javascript ファイルを作成します。

tsc "./Main.ts" -out "./script/myProject_debug.js" --declarations

次に、このファイルを次のように Google Closure (compiler.jar) で難読化します。

java -jar ./compiler/compiler.jar --compilation_level ADVANCED_OPTIMIZATIONS --js "./script/myProject_debug.js" > "./script/myProject.js".

しかし、結果の難読化/最適化されたコードを実行すると、次のエラーが発生しました: Uncaught TypeError: Cannot read property 'prototype' of undefined

次の難読化されていない JS コード (tsc コマンドで生成) と一致します。

var __extends = this.__extends || function (d, b) {
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
}

この部分は「extends」Typescript キーワードを変換するために使用され、b に相当するものは未定義です。

誰かが同様のエラーを抱えているか、または Typescript コンパイル済みファイルを使用して Google Closure で難読化できる解決策を得ていますか?

uglifyjs コマンドを試してみたところ、出力ファイルは完全に機能しましたが、完全な難読化 (クラス、引数、変数、メソッドなど) が必要です。また、Google Closure によって提供される追加の最適化も歓迎します。

ありがとうございます!

4

2 に答える 2

3

の定義に__extendsは、表示されるエラーの原因となっている可能性が最も高い問題があります。

var __extends = this.__extends || function (d, b) { ... };

this.__extends参照は と同じことを意図していますが、Closure -compiler は、グローバル コンテキストでの への参照が実際にはオブジェクトであることwindow.__extendsを認識していません (または認識しようとさえしません) 。コンパイラでコンパイルすると、次の警告が表示されます。thiswindow--warning_level=VERBOSE

Dangerous use of the global this object at line 1 character 16
var __extends = this.__extends || function (d, b) {
                ^

さらに、これthis.__extendsは外部/未定義のプロパティへの参照であり、コンパイラはレベルでそれについても警告していVERBOSEます。

Closure-compiler Service UIを使用して、警告なしでコンパイルするように定義を変更し、注釈を付けました。

// ==ClosureCompiler==
// @compilation_level ADVANCED_OPTIMIZATIONS
// @warning_level VERBOSE
// @output_file_name default.js
// @formatting pretty_print
// ==/ClosureCompiler==

var __extends = window['__extends'] || function (d, b) {
  /** @constructor */
  function __() { this.constructor = d; }
  __.prototype = b.prototype;
  d.prototype = new __();
}

/**
 * @constructor
 * @extends {String}
 */
function foo2() {this.foo = 'bar'; }
__extends(foo2, String);

var bar2 = new foo2;
alert(bar2.toLowerCase);

変更およびコンパイルされたコードの JSFiddle

于 2012-11-30T14:35:22.857 に答える
0

問題が見つかりました。

前に言ったように、 b は では定義されていません:

var __extends = this.__extends || function (d, b) {
   function __() { this.constructor = d; }
   __.prototype = b.prototype;
   d.prototype = new __();
}

typescript を javascript に「コンパイル」するとき、プロジェクトごとに 1 つの名前空間を取得したが、この名前空間に関連するすべてのクラスを別々のファイルに書き込む場合、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= {}));

その仕組みは正確にはわかりませんが、このコードに問題がなく、JSがそれを処理できる場合でも、どこかで google-closure-compiler がいくつかのクラスを削除しました。そのため、いくつかの依存関係が欠落しており、b は未定義でした。

したがって、次のように名前空間を宣言すると、エラーが発生しなくなることがわかりました(「メイン」クラスが使用されているか、参照を保持している限り、クロージャーは最終的な難読化されたjsファイルにすべてのクラスを保持しますグローバル ウィンドウ オブジェクトの名前空間) :

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= {}));

typescriptlang.org で問題を開くと思います。ちなみに、生成されるファイルサイズを最適化しています。

回答ありがとうございます。

于 2012-12-01T13:32:40.260 に答える