Как сохранить глобальные переменные в JavaScript при использовании компилятора Closure с расширенной оптимизацией? - PullRequest
5 голосов
/ 28 мая 2011

У меня есть собственная библиотека Javascript, которую я хочу минимизировать с помощью компилятора Google Closure с расширенной оптимизацией.Глядя на документы , я вижу, как объявлять функции, которые используются за пределами библиотеки.

Однако я не смог найти способ сохранить глобальные переменные, объявленные в моей библиотеке.Компилятор Closure просто удаляет их, потому что считает, что они никогда не используются.Кто-нибудь может помочь?

Редактировать: пример кода:

var variable_1 = true;

Это определено глобально в самом начале моей библиотеки, но никогда не используется в самой библиотеке.Он используется за пределами библиотеки, когда он включен в какую-то страницу.Но этот компилятор Closure не знает, и поэтому он удаляет эти объявления.

Ответы [ 3 ]

7 голосов
/ 28 мая 2011

Компилятор замыкания не может удалить глобальные переменные, объявленные как window["variable_1"] = true

Я рекомендую вам писать в window напрямую для глобальных переменных, а также рекомендую использовать строковые литералы для имен переменных, чтобы замыкание не уменьшало его.

3 голосов
/ 29 мая 2011

Несмотря на то, что вы можете ссылаться на «истинную» глобальную переменную путем замены всего использования этой глобальной переменной на window["varname"], обычно «не рекомендуется» загрязнять глобальное пространство имен. Закрывающий компилятор разработан, чтобы отговорить вас от этого.

CAVEAT : window["varname"] и var varname - это не одно и то же, поскольку «окно» не всегда может быть глобальным объектом в средах без браузера. На самом деле, Closure Compiler предполагает, что глобальный объект и «окно» различны. Например, window["varname"] будет компилироваться в window.varname вместо var varname. Они НЕ одинаковы, хотя в браузере они работают аналогично.

Лучше всего создать объект глобального пространства имен, а затем экспортировать только этот один объект. Все ваши «глобальные» переменные должны стать свойствами этой глобальной переменной пространства имен. Преимущества:

  1. Все эти глобальные переменные переименованы в более короткие версии
  2. Может произойти встраивание констант
  3. Компилятор Closure автоматически «сглаживает» пространство имен, так что ваш код не будет медленнее
  4. Превосходное запутывание
  5. Ваш код также работает в не браузерной среде. Помните, что «окно» не всегда существует (например, в коде на стороне сервера), а «глобальный объект» не всегда может быть «окном»

Если у вас есть глобальные переменные, которые пользователь должен прочитать / установить, чтобы использовать вашу библиотеку, это также не рекомендуется. Лучше предоставить API для объекта глобального пространства имен, а затем предоставить общедоступные API, как обычно, через объект окна: window["myLib"]["setConfig"] = myLib.setConfig.

В вашем случае, если у вас есть глобальные переменные, используемые в других частях кода, не скомпилированного с помощью Closure, вы должны учитывать:

  1. Лучше ли поместить объявление этих переменных вне файла, скомпилированного с помощью Closure
  2. Почему вы не помещаете объявление этих переменных вместе с кодом, использующим их
  3. Должны ли вы на самом деле компилировать Closure весь код, а не только часть (это возможно? Вы используете другую библиотеку?)
1 голос
/ 03 января 2012

Я только что столкнулся с этим, и у меня есть собственное решение.

Создайте свою целую библиотеку внутри самовыполняющейся функции, поместив все свойства объекта в виде строк (хотя бы один раз для каждого свойства), например:

(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')();, а затем присвоить ей эту переменную.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...