Пакетные приложения Google Closure и Chrome: совместимость?

Я использую Google Closure и пытаюсь создать упакованное приложение Chrome.

Мой вызов goog.require вызывает ошибку:

Uncaught document.write() is not available in packaged apps.

Виновник находится в base.js

goog.writeScriptTag_ = function(src) {
  if (goog.inHtmlDocument_()) {
    var doc = goog.global.document;

    // If the user tries to require a new symbol after document load,
    // something has gone terribly wrong. Doing a document.write would
    // wipe out the page.
    if (doc.readyState == 'complete') {
      // Certain test frameworks load base.js multiple times, which tries
      // to write deps.js each time. If that happens, just fail silently.
      // These frameworks wipe the page between each load of base.js, so this
      // is OK.
      var isDeps = /\bdeps.js$/.test(src);
      if (isDeps) {
        return false;
      } else {
        throw Error('Cannot write "' + src + '" after document load');
      }
    }

    doc.write(
        '<script type="text/javascript" src="' + src + '"></' + 'script>');
    return true;
  } else {
    return false;
  }
};

Является ли Google Closure несовместимым с упакованными приложениями Google Chrome? Closure имеет так много преимуществ для больших проектов Javascript, что действительно трудно отказаться от такого ценного инструмента.

РЕДАКТИРОВАТЬ: я знаю, что если компилятор Closure используется в дополнение к библиотекам Closure, goog.require отсутствует, но это явно усложняет разработку и отладку.


person Paul Draper    schedule 06.06.2013    source источник


Ответы (1)


Режим разработки закрытия и пакетное приложение Chrome - - document.write() недоступен в песочнице упакованных приложений

Пока вы запускаете его без компиляции или не компилируете с расширенной компиляцией, вам нужно переписать doc.write с помощью document.createElement("script");

Поэтому замените строку doc.write на:

  var script = document.createElement('script');
  script.src = src;
  script.type = 'text/javascript';
  goog.global.document.getElementsByTagName("head")[0].appendChild(script);
  return true;

Предварительно скомпилированный код не нуждается в этом, поскольку он объединяет весь используемый код в один файл.

person HMR    schedule 06.06.2013
comment
Это гарантированно сработает? Казалось, что когда я пробовал это для динамической загрузки Javascript в другом проекте, сценарии выполнялись асинхронно в неопределенном порядке. - person Paul Draper; 06.06.2013
comment
Я подтвердил это наблюдение. Это может работать для небольших файлов или чего-то еще, но javascript загружается и оценивается непоследовательно. - person Paul Draper; 06.06.2013
comment
Это должно быть причиной того, что Google использует document.write. Вы можете попробовать calcdeps.py и создать теги ‹script для всех необходимых файлов. Вы можете использовать список вывода, чтобы получить список, а затем создать теги ‹script для загрузки всех необходимых файлов js перед их использованием. goog.require должен обнаружить, что файл уже загружен, и не будет выполнять document.write. developers.google.com/closure/library/docs/calcdeps#opts - person HMR; 07.06.2013
comment
Да, и это то, что я закончил делать. Это не красивое решение, и я надеюсь, что со временем появится лучшее, но calcdeps и вставка в html работают. - person Paul Draper; 08.06.2013