Как я могу загрузить свой собственный модуль js с помощью goog.provide и goog.require? - PullRequest
16 голосов
/ 17 декабря 2009

Мы пытаемся переключить упаковку для нашего проекта с додзё на закрытие Google, но пока нам не повезло. Вот простой пример, который иллюстрирует то, что мы пытаемся достичь:


<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <script type="text/javascript" src="runtime/src/core/lib/goog-rev26/base.js"></script>
        <script>
            goog.require("foo.bar");
            function main() {foo.bar.echo("hello world")}
        </script>
    </head>
<body onload="main()">
</body>
</html>

Тогда в /foo/bar.js У меня есть:


goog.provide("foo.bar");
foo.bar.echo = function(s) {console.debug(s);}

Ошибки, которые я получаю в firebug, следующие:

goog.require could not find: foo.bar
foo is not defined

Когда я просматриваю вкладку Net, нет запроса http для извлечения файла - я ожидал, что библиотека закрытия создаст тег сценария для извлечения bar.js.

помощь! ;)

Ответы [ 7 ]

13 голосов
/ 05 января 2010

Я понял это, и это не очень сложно, но есть несколько ошибок.

По сути, вы можете использовать скрипт генерации зависимостей calcdeps.py ( вы должны прочитать calcdeps.py docs ) в одном из нескольких режимов:

  1. Создание файла deps.js
  2. Объединение всего в один файл, при необходимости компиляция его с помощью компилятора закрытия.

Для разработки вы должны использовать (1), так как он позволяет вам не запускать calcdeps.py после редактирования источников JS, если вы не внесете изменения в дерево зависимостей. Остальная часть ответа об этом, я еще не пробовал другой.

Вот что я сделал для его генерации:

#!/bin/bash
cd closure-library/closure/goog
python ../bin/calcdeps.py -p ../../../js -o deps > ../../../my-deps.js

... при условии следующей структуры каталогов:

project/
  closure-library/ (as checked out from SVN)
  js/ (my JS code)
  app.html

(параметр -p перебирает все js-файлы в указанном каталоге, и в документах говорится, что вы можете указать несколько каталогов для поиска, если нужно.)

Вышеуказанный вызов создает файл my-deps.js рядом с основным app.html, который я использую для запуска приложения. Созданный файл содержит информацию о моих JS-файлах в js/ и выглядит следующим образом:

goog.addDependency('../../../js/controllers.js', ['proj.controllers'], []);
goog.addDependency('../../../js/ui.js', ['proj.ui'], ['proj.controllers']);

- где первая строка это путь к моему файлу JS относительно closure-library / closure / goog / base.js (это важно!), Второй массив - список goog.provide -d строк, а последний массив - это список goog.require -d строк.

Теперь в app.html у меня есть:

<script src="closure-library/closure/goog/base.js"></script>
<script src="my-deps.js"></script>
<script>
  goog.require("proj.ui");
</script>
<script>
  // here we can use the required objects
</script>

Примечание:

  1. В дополнение к base.js для closure, я включаю мои сгенерированные deps.js
  2. Как упоминалось в руководстве , вызов goog.require должен быть в отдельном теге сценария , поскольку он добавляет тег сценария для загрузки необходимых сценариев, и они загружаются после завершения обработки текущего тега сценария. .

Gotchas:

  1. Описанная выше проблема с путями относительно base.js. goog.require создает URL-адрес сценария для загрузки путем объединения базового URL-адреса base.js (т. Е. Без base.js leafname) и первого параметра для goog.addDependency в deps.js.
  2. calcdeps.py плохо работает в Windows, в частности с использованием обратной косой черты в строковых литералах deps.js
  3. Если что-то не работает, вы можете просмотреть все вопросы, касающиеся calcdeps , и убедиться, что у вас есть актуальная проверка.
8 голосов
/ 15 июля 2010

Обновление !!!

Новая версия calcdeps.py немного меняет игру. Для создания вашего deps.js вам нужно использовать флаг -d. например:

python path-to-closure-library/closure/bin/calcdeps.py -i path-to-your-src/requirements.js -o deps -d path-to-closure-library/closure/ -p path-to-your-src/ --output_file=path-to-your-src/deps.js

Для компиляции:

python path-to-closure-library/closure/bin/calcdeps.py -i path-to-your-src/requirements.js -d path-to-closure-library/closure/ -p ./ --output_file=path-to-your-release/scripts.min.js -c path-to-compiler/compiler.jar -f "--compilation_level=ADVANCED_OPTIMIZATIONS" -f "--debug=true" -f "--process_closure_primitives=true" -f "--manage_closure_dependencies=true" -o compiled

Таким образом, процесс на самом деле теперь намного проще, но вы должны использовать свои возможности ESP, чтобы узнать об этом как о полностью недокументированном. Calcdeps.py теперь также не работает с Python 3.1 на окнах, так что это также куча веселья. Несколько хаков заставили меня работать (что я не буду здесь описывать, потому что я не программист на Python и должны быть более эффективные способы сделать это).

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

Guido

1 голос
/ 29 декабря 2009

Да, вы должны использовать calcdepds.py. После долгих проб и ошибок я создал большую запись в блоге, чтобы выяснить, как лучше всего это сделать, а также расскажу о различиях между dojo.require и goog.require:

http://apphacker.wordpress.com/2009/12/28/howto-how-to-use-goog-require-and-goog-provide-for-your-own-code/

1 голос
/ 17 декабря 2009

Мне удалось заставить его работать, добавив следующее к deps.js:
goog.addDependency('../../../foo/bar.js', ['foo.bar'], []);

Firefox теперь отправляет http-запрос на /foo/bar.js, когда встречается с оператором goog.requires.

Тем не менее, файл содержит этот комментарий:
// This file has been auto-generated by GenJsDeps, please do not edit.

Согласно этот , GenJsDeps совпадает с calcdeps.py. Если вы посмотрите на документацию, похоже, что есть переключатель -o deps, который будет генерировать deps.js, поэтому он не редактируется вручную.

0 голосов
/ 21 июня 2013

решение:

  • загрузить закрытие для внешнего проекта (или активов, что угодно).

  • не беспокойтесь о настройках загрузки, задержки, игры с асинхронностью и т. Д.

  • они не будут работать (они также очень плохой шаблон дизайна и чрезвычайно хромает ..)

- это ваш main.js, где вы динамически внедряете свой код в DOM (например, создаете букмарклет или что-то в этом роде):

/**
 * loads the base.js of google closure.
 * http://code.google.com/p/closure-library/
 */

(function() {
  var s = document.createElement('script');
  s.type = "text/javascript";
  s.src = "./assets/closure/goog/base.js";
  s.async = true;
  document.getElementsByTagName("body")[0].appendChild(s);
}());

/**
 * activated from the base.js as JSONProtocol.
 */
window['starter'] = function() {
  console.log("hi...");
};

сейчас:

  • изменить ваш base.js

добавить конец файла

......
.......
........

/**
 * run the method when done load. just like JSONProtocol.
 */
window.setTimeout(function() {
  window['starter']();
}, 5);
  • ваш " callback " просто активирует стартер, когда файл завершил рендеринг,

  • работает отлично и асинхронно загружает каждый ресурс.

приписка

  1. синтаксис окна ['....'] таков, что вы можете безопасно использовать closure-compiler до максимума и всегда использовать одно и то же имя (хотя есть и другие способы сделать это, но это простой «всегда работающий») "путь ..).

2. на base.js вы также можете избежать тайм-аута и просто использовать

......
.......
........

/**
 * run the method when done load. just like JSONProtocol.
 */
window['starter']();

но, как правило, современные браузеры работают лучше, когда вы заключаете их в "не все равно, просто сделайте это в конце, как, например, обратный вызов JSONProtocol" вещи-

Тайм-ауты (в основном используются со значениями от 0 до 5) не прерываются как тайм-ауты, а как способ нарушить синхронность кодового блока, позволяющего действительно "контекстное переключение" поведение, подобное.

хотя там есть дополнительные издержки.

0 голосов
/ 11 ноября 2010

Любой способ заставить работать пользовательские модули, по крайней мере для версии для разработчиков, состоит в том, чтобы вручную включить файлы js в заголовочный раздел html-страницы после включения файла google base.js.

<script type="text/javascript" src="js/closure/goog/base.js"></script>
<script type="text/javascript" src="js/closure/custom/custom.js"></script>
<script type="text/javascript" src="js/closure/custom/sub/sub.js"></script>
...

Но вы должны позаботиться о последовательности включения самостоятельно. Для не очень больших пользовательских наборов файлов это работает хорошо. Для рабочей версии вам все же лучше использовать компиляцию исходного кода js, чтобы получить все преимущества библиотеки закрытия.

0 голосов
/ 23 февраля 2010

Вот небольшой проект, над которым я работал, который может быть вам полезен: http://github.com/fintler/lanyard

Посмотрите build.xml, файл с именем lanyard.js и все файлы, расположенные в src / geom /*.

В build.xml есть пример того, как вызывать calcdeps.py через ant для всех js, расположенных в src. Возможно, это не лучший способ сделать что-то, но пока он работает для меня.

...