5

高度な最適化を備えた Google クロージャー コンパイラを使用して縮小したい独自の Javascript ライブラリがあります。ドキュメントを見ると、ライブラリの外で使用される関数を宣言する方法がわかります。

ただし、ライブラリで宣言されたグローバル変数を保持する方法が見つかりませんでした。クロージャーコンパイラーは、それらが使用されていないと考えているため、それらを削除するだけです。誰でも助けることができますか?

編集: コード例:

var variable_1 = true;

これは私のライブラリの冒頭でグローバルに定義されていますが、ライブラリ自体では使用されていません。一部のページに含まれている場合は、ライブラリの外で使用されます。しかし、その Closure コンパイラは知らないため、これらの宣言を削除します。

4

3 に答える 3

7

クロージャ コンパイラは、次のように宣言されたグローバル変数を削除できません。window["variable_1"] = true

グローバル変数については直接書き込むことをお勧めwindowします。また、変数名に文字列リテラルを使用して、クロージャーによって縮小されないようにすることもお勧めします。

于 2011-05-28T13:26:25.187 に答える
3

そのグローバル変数のすべての使用法を に置き換えることで「真の」グローバル変数を参照できますがwindow["varname"]、通常、グローバル名前空間を「汚染」することはお勧めできません。Closure Compiler は、これを行うのを思いとどまらせるように設計されています。

注意:window["varname"]var varnameは同じではありません。ブラウザ以外の環境では、「window」が常にグローバル オブジェクトであるとは限らないためです。実際のところ、Closure Compiler は、グローバル オブジェクトと「ウィンドウ」が異なると想定しています。たとえば、ではなく にwindow["varname"]コンパイルされます。ブラウザでは同様に機能しますが、同じではありません。window.varnamevar varname

グローバル名前空間オブジェクトを作成し、その 1 つのオブジェクトのみをエクスポートすることをお勧めします。すべての「グローバル」変数は、このグローバル名前空間変数の下のプロパティになる必要があります。利点:

  1. これらのグローバル変数はすべて、短いバージョンに名前が変更されます
  2. 定数のインライン化が発生する可能性があります
  3. いずれにせよ、Closure Compiler は名前空間を自動的に「平坦化」するため、コードが遅くなることはありません。
  4. 優れた難読化
  5. コードはブラウザ以外の環境でも機能します。「ウィンドウ」が常に存在するとは限らず (サーバー側のコードなど)、「グローバル オブジェクト」が常に「ウィンドウ」であるとは限らないことに注意してください。

ライブラリを使用するためにユーザーが読み取り/設定する必要があるグローバル変数がある場合も、推奨されません。グローバル名前空間オブジェクトで API を公開してから、通常どおり window オブジェクトを介して公開 API を公開することをお勧めしますwindow["myLib"]["setConfig"] = myLib.setConfig

あなたの場合、Closure でコンパイルされていないコードの他の部分で使用されているグローバル変数がある場合は、次のことを考慮する必要があります。

  1. これらの変数の宣言は、Closure によってコンパイルされるファイルの外に置く方が良いですか?
  2. それらの変数の宣言をそれらを使用するコードと一緒にしないのはなぜですか
  3. 一部だけではなく、すべてのコードを実際にクロージャー コンパイルする必要があります(可能ですか? 別のライブラリを使用しますか?)。
于 2011-05-29T05:38:45.023 に答える
1

私はちょうどこれに出くわしました、そして私は私自身の解決策を持っています。

自己実行関数内にライブラリ全体を作成し、次のようにすべてのオブジェクトプロパティを文字列として(少なくともプロパティごとに1回)配置します。

(function () {
    var myLibrary = {
        'myMethod' : function () {
            ...
        }
    }
    myLibrary.myMethod['propertyOfTheMethod'] = '';
}());

これを外部からアクセスできるようにする通常の方法はvar myLibrary =、関数の前とreturn myLibrary最後に配置して、グローバル変数に割り当てられるようにすることです。ただし、関数はグローバルスコープで実行されるため(自己実行型であるため)、this文字列リテラルを使用するプロパティを作成できます。だから完全に:

(function () {
    var myLibrary = {
        'myMethod' : function () {
            ...
        }
    }
    myLibrary.myMethod['propertyOfTheMethod'] = '';
    this['myLibrary'] = myLibrary;
}());

ただし、これはの下では機能しません"use strict";。厳密モードでグローバル変数を取得する最良の方法はvar global = Function('return this')();、変数をそれに割り当てることです。

于 2012-01-03T10:17:02.647 に答える